Java中的内存泄漏-程序员宅基地

技术标签: Java  Android  

本文转自https://github.com/francistao/LearningNotes/blob/master/Part2/JavaSE/Java%E4%B8%AD%E7%9A%84%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.md该github下有很多Android技术的知识点,强烈推荐下!


#Java中的内存泄漏


1.Java内存回收机制

不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题。在Java语言中,判断一个内存空间是否符合垃圾收集标准有两个:一个是给对象赋予了空值null,以下再没有调用过,另一个是给对象赋予了新值,这样重新分配了内存空间。

2.Java内存泄漏引起的原因

内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。

Java内存泄漏的根本原因是什么呢?长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java中内存泄漏的发生场景。具体主要有如下几大类:

1、静态集合类引起内存泄漏:

像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。

例如

Static Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{
Object o = new Object();
v.add(o);
o = null;
}

在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身(o=null),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。

例如:

public static void main(String[] args)
{
Set<Person> set = new HashSet<Person>();
Person p1 = new Person("唐僧","pwd1",25);
Person p2 = new Person("孙悟空","pwd2",26);
Person p3 = new Person("猪八戒","pwd3",27);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!
p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变

set.remove(p3); //此时remove不掉,造成内存泄漏

set.add(p3); //重新添加,居然添加成功
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!
for (Person person : set)
{
System.out.println(person);
}
}

3、监听器

在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

4、各种连接

比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。

5、内部类和外部模块的引用

内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法如: public void registerMsg(Object b); 这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。

6、单例模式

不正确使用单例模式是引起内存泄漏的一个常见问题,单例对象在初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部的引用,那么这个对象将不能被JVM正常回收,导致内存泄漏,考虑下面的例子:

class A{
public A(){
B.getInstance().setA(this);
}
....
}
//B类采用单例模式
class B{
private A a;
private static B instance=new B();
public B(){}
public static B getInstance(){
return instance;
}
public void setA(A a){
this.a=a;
}
//getter...
} 

显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较复杂的对象或者集合类型会发生什么情况



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bit_kaki/article/details/78023280

智能推荐

如果结束进程拒绝访问,可以尝试以下-程序员宅基地

文章浏览阅读2.3k次。如果taskkill /f /pid 123 出现拒绝访问时,可使用以下方式删除进程:wmic process where name=‘qq.exe’ delete11如果这样还杀不死,恐怕就要进[安全模式]删除了。杀了进程,想删除文件,可以这样删除cmd下运行:DEL /F /A /Q 文件名抄自-吉吉教主...

Visual Studio-IIS Express 支持局域网访问配置-程序员宅基地

文章浏览阅读201次。转自:http://www.itnose.net/detail/6132793.html使用Visual Studio开发Web网页的时候有这样的情况:想要在调试模式下让局域网的其他设备进行访问,以便进行测试。虽然可以部署到服务器中,但是却无法进行调试,就算是注入进程进行调试也是无法达到自己的需求;所以只能在Visual Studio-IIS Express 中进行调试。而于此将..._visual studio iis express debug localhost

Oracle 数据库层级遍历查询_oracle遍历查询结果集-程序员宅基地

文章浏览阅读1.5k次。首先创建一张用于测试的表,表明为 TREE,表中有3个字段,分别是,ID,NANE,UP_ID。UP_ID 是 ID 的上层,主要实现树形结构的存储。1.1 初始化测试数据1.1.1 写入数据1.1.2 树形结构如下图root(8)一(1)二(2)三(3)五(5)root(6)四(4)2. 树形结构遍历查询2.1 从父节点遍历查询结果如下:2.2 从子节点开始遍历查询结果是:2.3 start with 条件 connect by prior_oracle遍历查询结果集

centos安装cmake-程序员宅基地

文章浏览阅读5.1k次。安装gcc的软件依赖(已安装请跳过)yum install -y gcc gcc-c++ make automake安装wget(已安装请跳过)yum install -y wget下载cmake源代码包,可以去官网查看最新版的下载地址:https://cmake.org/download/wget “https://cmake.org/files/v3.10/cmake-3.10...._centos安装cmake

Nova和Kuryr的下一步是什么,不断发展的IT架构以及更多OpenStack新闻-程序员宅基地

文章浏览阅读80次。有兴趣跟踪开源云中正在发生的事情吗? Opensource.com是您在开源云基础设施项目OpenStack中获取新闻的来源。 Web上的OpenStack 关于OpenStack,有很多有趣的东西。 这是一个样本: OpenStack Mitaka 版本 :Nova和Kuryr的下一步是什么? 不断发展的IT体系结构 :可能很难。 云原生如何需要文化变革 :转换IT运营..._kuryr nova

用php的系统函数处理字符串,PHP系统函数----常用字符串函数-程序员宅基地

文章浏览阅读126次。去空格或者其他字符串trim() :去除首尾空白字符空白字符包括:\t,\n,"",\0,\xoBtrim($str,[$type]);rtrim():去除尾部空白字符chop() :rtrim别名ltrim():去除头部空白字符dirname():传入一个文件路径,返回去除该文件名的文件路径dirname($path);字符串生成与转化str_pad():填充字符串str_pad($str,$l..._3. 编写 个php函数,接受 个字符串参数,返回该字符串中最 的连续 串,

随便推点

竹云+巨杉丨互信认证 安全可靠_竹云iam 操作手册-程序员宅基地

文章浏览阅读2.3k次。近日,竹云IAM统一身份安全管理平台与巨杉数据库完成技术兼容和认证工作,经双方共同严格测试,巨杉数据库V3.4与竹云身份管理与访问控制平台软件V6.0,竹云安全内控管理平台软件V6.0在兼容性、可靠性和性能等方面均能满足用户的关键性应用需求,双方将共同打造基于分布式数据库的微服务架构身份管理与访问控制系统联合解决方案。随着国家对重点行业“安全可控信息技术”的要求不断深化,也越来越强调基于国产生态环境下信息系统的自主可控。作为拥有完全自主可控国产化技术的高新科技企业,竹云与巨杉的紧密合作将为用户提供更高效、_竹云iam 操作手册

c++中string和char*的类型转换,并求string的长度_c_str() 长度-程序员宅基地

文章浏览阅读1.5k次。一、char*(char)转string(直接赋值)#include<iostream>#include<string>#include <typeinfo>using namespace std;int main(){ string str; const char* p = "ch"; //char p[] = "ch"; str = p; cout << str << endl; _c_str() 长度

linux查看cpu状态相关命令_linux查看cpu命令-程序员宅基地

文章浏览阅读1.9w次。linux查看cpu状态相关命令_linux查看cpu命令

企业信息安全整体架构_信息安全框架 安全制定、安全建设、运营、应急-程序员宅基地

文章浏览阅读3k次,点赞3次,收藏21次。在网络安全中,除了采用上述技术措施之外,加强网络的安全管理,制定有关规章制度,对于确保网络的安全、可靠地运行,将起到十分有效的作用。安全体系建设中,安全管理是一个非常重要的部分。任何的安全技术保障措施,最终要落实到具体的管理规章制度以及具体的管理人员职责上,并通过管理人员的工作得到实现。..._信息安全框架 安全制定、安全建设、运营、应急

android真机调试时使用SQLite3查询数据库_android 使用sqlite3查询数据库-程序员宅基地

文章浏览阅读1w次。当使用真机调试android程序时,有时需要在adb shell 里查询SQLite数据库。而有的手机例如华为p6,既没有root又没有自带SQLite3工具,那么如何解决这个问题呢? 1、root手机。在网上下载一键root工具,如百度一键root,并允许,使得手机获得root权限; 2、adb root。下载 Superuser Permissions 软件并运行。在cmd_android 使用sqlite3查询数据库

vscode gcc编译报错找不到路径_vscode无法找到gcc-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏3次。最近在学习vscode配置命令行编译,在网上参考了很多教程。基本上按部就班的配置。可是到最后总显示报错,找不到文件路径,大抵为-environment-cd xxxxxxxxxx No such file or directory.后来我发现,一切都tm是中文路径的锅。在安装gcc的时候,gcc目录下不能有中文路径。这一点我也注意到了。我后来发现,文件目录所在路径也不能有中文,就cpp文件,好像gcc也没法识别找到。我将中文目录路径去掉之后就编译成功了..._vscode无法找到gcc

推荐文章

热门文章

相关标签