01.发生了什么?
Nani,Java不会自动管理内存?怎么会有内存泄漏泄漏泄漏!
Java最强大的功能之一是垃圾收集机制。它不需要像C ++那样手动管理内存,所以很高兴成为一名Java程序员,只是New New New。无论如何,Java将自动回收过期的对象。
然后Java自动管理内存,怎么会有内存泄漏,是Jvm越野车?别担心,慢慢听我说。
02.如何判断可以回收
让我们首先了解Jvm如何判断物体是否可以回收利用。通常有两种方式,一种是引用计数方法,另一种是可访问性分析。
引用计数方法:每个对象都有一个引用计数属性。添加新引用时,计数增加1.当引用被释放时,计数减1.当计数为0时,它可以被回收。
这种方法看起来很简单,但是如果A指的是B而B指的是A,那么它们就不再使用了,但是因为相互参考计算器=1永远不能被回收。
这种方法很简单,并没有解决对象之间循环引用的问题。
可达性分析:从GC根搜索下来,搜索所采用的路径称为参考链。当一个对象连接到没有任何参考链的GC根时,它证明该对象不可用,然后虚拟机判断为可回收对象。
可达性分析可以解决循环引用的问题。
那么gc的根对象是什么?
虚拟机堆栈中引用的对象
方法区域中类静态属性引用的对象
方法区域JNI中的常量引用的对象[通常称为Native]引用该对象。大多数当前的主流虚拟机使用可达性分析来确定对象是否可以由GC回收。 03.在什么情况下会有内存泄漏?由于可达性分析似乎非常傲慢,怎么会有内存泄漏?我们来看看内存泄漏的定义。内存泄漏意味着程序不再使用的对象或变量总是在内存中占用。该对象可能不再使用,但是有其他对象保存对此对象的引用,这会导致GC不回收对象,在这种情况下会发生内存泄漏。编写程序以使内存泄漏持有对短期对象的引用的长寿命对象可能会有内存泄漏,尽管不再需要短暂的对象,但它不能被回收,因为长期存在的对象保留其引用。
公共类Simple {
对象对象;
Public void method1(){
Object=new Object();
//.其他代码
}
}
事实上,这里的对象实例我们希望它只用在method1()方法中,并且不会在别处使用,但是当执行method1()方法时,不会考虑对象对象分配的内存立即。它是一个可以释放的对象。它仅在释放由Simple类创建的对象时释放。严格来说,这是一个内存泄漏。
解决方案是在method1()方法中使用object作为局部变量。
公共类Simple {
对象对象;
Public void method1(){
Object=new Object();
//.其他代码
Object=null;
}
}
当然,您可能认为此方法不会产生太大影响,但如果在某些项目中,方法在一分钟内被调用数万次,则会出现明显的内存泄漏。
2集合中的内存泄漏,如HashMap,ArrayList等,这些对象经常有内存泄漏。例如,当它们被声明为静态对象时,它们的生命周期将与应用程序的生命周期一样长,这很容易导致内存不足。
下面给出了收集内存泄漏的示例。
矢量v=new Vector(10); for(int i=1; i