01。这是怎么回事?Nani,Java不会自动管理内存吗?怎么会内存泄露!Java最强大的特性之一就是垃圾回收机制,不需要像C++那样手动管理内存,所以作为Java程序员很开心,NewNewNew就行了,反正Java会自动回收过期的对象。..那么Java是自动管理内存的,怎么会出现内存泄漏呢?Jvm中有错误吗?别着急,慢慢听我说。.02.如何判断是否可以回收首先,我们了解一下Jvm是如何判断一个对象是否可以被回收的。一般有两种方式,一种是引用计数法,一种是可访问性分析。引用计数方法:每个对象都有一个引用计数属性,添加引用时计数加1,释放引用时减1,计数为0时可以回收。这个方法貌似很简单,但是如果A引用B,B又引用A,即使此时不再使用,也永远无法回收,因为相互引用calculator=1。这种方法比较简单,不能解决对象间循环引用的问题。ReachabilityAnalysis:从GCRoots开始向下搜索,搜索所经过的路径称为引用链。当一个对象没有任何引用链连接到GCRoots时,证明该对象不可用,虚拟机判断为可回收对象。可达性分析可以解决循环引用的问题。那么什么是gcroots对象呢?虚拟机栈中引用的对象方法区类静态属性引用的对象本地方法栈中常量引用的对象当前主流虚拟机中JNI[Native]引用的对象大多采用可达性分析判断对象是否存在可以被GC回收。03.什么情况下会发生内存泄漏?既然可达性分析看起来很厉害,怎么会出现内存泄漏呢?让我们看一下内存泄漏的定义。内存泄漏是指一个不再被程序使用的对象或变量一直被占用在内存中。有可能这个对象不再被使用,但是有其他对象持有这个对象的引用,这会导致GC无法回收这个对象,在这种情况下就会发生内存泄漏。写程序引起内存泄漏①长寿命对象持有短寿命对象的引用很可能引起内存泄漏。虽然短寿命对象不再需要,但是由于长寿命对象持有它的引用不能被回收。publicclassSimple{Objectobject;publicvoidmethod1(){object=newObject();//...其他代码}}这里的对象实例,其实我们期望它只在method1()方法中使用,并不会在其他地方使用,但是当method1()方法执行时,object对象分配的内存不会被认为是可以立即释放的对象,只有在Simple类创建的对象释放后才会释放.严格来说,这是内存泄漏。解决方案是在method1()方法中使object成为局部变量。publicclassSimple{Objectobject;publicvoidmethod1(){object=newObject();//...其他代码object=null;}}当然你可能认为这个方法不会有太大的影响,但是如果在一些项目中,当一个方法在一分钟内被调用上万次,就会出现明显的内存泄漏。②集合中的内存泄漏,比如HashMap、ArrayList等,这些对象经常会出现内存泄漏。例如,当它们被声明为静态对象时,它们的生命周期将与应用程序的生命周期一样长,这很容易导致内存不足。下面给出了集合内存泄漏的示例。vectorv=newVector(10);for(inti=1;i<100;i++){Objecto=newObject();v.add(o);o=null;}//此时所有Object对象都没有被释放,因为变量v指的是这些对象。在本例中,我们循环申请Object对象,并将申请到的对象放入一个Vector中。如果我们只释放引用本身,那么Vector仍然引用这个对象,所以这个对象是不可回收的GC。因此,如果一个对象在添加到Vector后必须从Vector中删除,最简单的方法是将Vector对象设置为null。以上两种是最常见的内存泄漏情况。当然,还有一些内存泄漏的例子,这里就不一一列举了。有兴趣的同学可以上网查资料。04.内存泄漏和内存溢出很多同学总是对内存泄漏和内存溢出的区别感到困惑。它们是两个完全不同的概念,它们之间又存在一些联系。Memoryoverflowoutofmemory是指程序在申请内存时,没有足够的内存空间供其使用,出现内存溢出;memoryleak内存泄漏是指程序在申请内存后无法释放申请的内存空间。内存泄漏的危害可以忽略,但是内存泄漏累积的后果是非常严重的。不管用多少内存,迟早都会用完。所以内存泄漏可能会导致内存溢出,但是内存溢出并不完全是内存泄漏造成的,也有可能是使用了过多的大对象造成的。05.如何检测内存泄漏***一个重要的问题是如何检测Java内存泄漏。目前,我们通常会使用一些工具来检查Java程序中的内存泄漏。市场上有几种专业的Java内存泄漏检查工具。它们的基本工作原理相似。它们都监视Java程序运行时所有对象的申请和释放,收集内存管理的所有信息。可视化。开发人员将使用这些信息来确定程序是否存在内存泄漏。这些工具包括Plumbr、EclipseMemoryAnalyzer、JProbeProfiler、JVisualVM等。06.***以上内容其实是我以前经常面试的内容之一,通过一系列的问题来考察Java程序员对Jvm的理解。比如我一般会问面试官,Java有内存泄漏吗?大多数人会回答是,然后我会问如果让你写一个导致内存泄漏的程序,你会怎么写?大多数程序员将无法回答。如果面试官能回答上面的问题,我再和面试官聊聊,内存泄漏和内存溢出之间有没有联系,日常工作中如何避免写出内存泄漏的代码,是否有Jvm相关的问题在生产的时候,排除故障的思路和步骤等等。【本文为专栏作家《纯洁的微笑》原创稿件,转载请微信♂联系作者获得授权】点此查看该作者更多好文
