纳尼,Java 存在内存泄泄泄泄泄泄漏吗?

  • 时间:
  • 浏览:0

01. 为什回事?

纳尼,Java 都有自动管理内存吗?为什愿因着会出現内存泄泄泄泄泄泄漏!

Java 最牛逼的有有另两个价值形式本来垃圾回收机制,后该像 C++ 不能 手动管理内存,全都 作为 Java 守护多多线程 员很幸福,只管 New New New 即可,反正 Java 会自动回收过期的对象。。。

没人 Java 都自动管理内存了,那为什会出現内存泄漏,难道 Jvm 有 bug? 何必 急,且听我慢慢道来。。

02. 为什判断不能被回收

先了解一下 Jvm 是为什判断有有另两个对象不能被回收。一般有四种 法律土法律法律依据,四种 是引用计数法,四种 是可达性分析。

引用计数法:每个对象有有有另两个引用计数属性,新增有有另两个引用时计数加1,引用释放时计数减1,计数为0时不能回收。

这种法律土法律法律依据看起来挺简单的,有之前 愿因着出現 A 引用了 B,B 又引用了 A,这那我能 算亲戚大伙都有再使用了,但愿因着相互引用 计算器=1 永远无法被回收。

此法律土法律法律依据简单,无法处置对象相互循环引用的间题。

可达性分析(Reachability Analysis):从 GC Roots 始于向下搜索,搜索所走过的路径称为引用链。当有有另两个对象到 GC Roots 没人任何引用链相连时,则证明此对象是不可用的,没人虚拟机就判断是可回收对象。

可达性分析不能处置循环引用的间题。

没人 gc roots 对象是那些呢

  • 虚拟机栈中引用的对象
  • 法律土法律法律依据区中类静态属性引用的对象
  • 法律土法律法律依据区中常量引用的对象
  • 本地法律土法律法律依据栈中JNI[即一般说的Native]引用的对象

目前主流的虚拟机中大多使用可达性分析的法律土法律法律依据来判定对象与否可被 GC 回收。

03. 那些状况下会出現内存泄漏

既然可达性分析好像愿因着很牛逼的样子了,为什愿因着都有出現内存泄漏呢,那亲戚亲戚大伙再来看一下内存泄漏的定义。

内存泄露本来指有有另两个不再被守护多多线程 使用的对象或变量时不时被处在在内存中。

有愿因着此对象愿因着不使用了,有之前 还有其它对象保持着此对象的引用,就会愿因 GC 不能回收此对象,这种状况下就会出現内存泄漏。

写有有另两个守护多多线程 让出現内存泄漏

①长生命周期的对象持有短生命周期对象的引用就很愿因着处在内存泄露,尽管短生命周期对象愿因着不再不能 ,有之前 愿因着长生命周期对象持有它的引用而愿因不能被回收。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...或多或少代码
    }
}

这里的 object 实例,着实亲戚大伙期望它只作用于 method1() 法律土法律法律依据中,且或多或少地方后该再用到它,有之前 ,当method1()法律土法律法律依据执行完成后,object 对象所分配的内存后该马上被认为是不能被释放的对象,不能在 Simple 类创建的对象被释放后才会被释放,严格的说,这本来四种 内存泄露。

处置法律土法律法律依据本来将 object 作为 method1() 法律土法律法律依据中的局部变量。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...或多或少代码
        object = null;
    }
}

当然亲戚大伙有愿因着会想就这有有另两个法律土法律法律依据也后该有多大影响,但愿因着在或多或少项目中,有有另两个法律土法律法律依据在一分钟之内调用上万次的那我,就会出現很明显的内存泄漏间题。

②集合中的内存泄漏,比如 HashMap、ArrayList 等,那些对象时不时会处在内存泄露。比如当它们被声明为静态对象时,它们的生命周期会跟应用守护多多线程 的生命周期一样长,很容易造成内存不足英文。

下面给出了有有另两个关于集合内存泄露的例子。

Vector v=new Vector(10);
for (int i=1;i<200; i++)
{
    Object o=new Object();
    v.add(o);
    o=null;
}
//此时,所有的Object对象都没人被释放,愿因着变量v引用那些对象。

在这种例子中,亲戚大伙循环申请 Object 对象,并将所申请的对象放进有有另两个 Vector 中,愿因着亲戚大伙仅仅释放引用四种 ,没人 Vector 仍然引用该对象,全都 这种对象对 GC 来说是不可回收的。

有之前 ,愿因着对象加入到 Vector 后,还不能 从 Vector 中删除,最简单的法律土法律法律依据本来将 Vector 对象设置为 null。

以上四种 是最常见的内存泄漏案例。当然还有或多或少内存泄漏的例子,这里就不再一一例举了,感兴趣的同学不能在网上找找资料。

04. 内存泄漏和内存溢出

全都 同学时不时搞不清楚,内存泄漏和内存溢出的区别,它俩是有有另两个完整篇 不同的概念, 它们之间处在或多或少关联。

内存溢出 out of memory,是指守护多多线程 在申请内存时,没人足够的内存空间供其使用,出現 out of memory;

内存泄露 memory leak,是指守护多多线程 在申请内存后,无法释放已申请的内存空间,一次内存泄露危害不能忽略,但内存泄露堆积后果很严重,无论几次内存,迟早会被占光。

全都 内存泄漏愿因着会愿因内存溢出,但内存溢出何必 完整篇 都 有愿因着内存泄漏,都有愿因着使用了很多的大对象愿因。

05. 怎么才能 才能 检测内存泄漏

最后有有另两个重要的间题,本来怎么才能 才能 检测 Java 的内存泄漏。目前,亲戚大伙通常使用或多或少工具来检查 Java 守护多多线程 的内存泄漏间题。

市场上已有几种专业检查 Java 内存泄漏的工具,它们的基本工作原理大同小异,都有通过监测 Java 守护多多线程 运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。开发人员将根据那些信息判断守护多多线程 与与否内存泄漏间题。

那些工具包括 Plumbr 、Eclipse Memory Analyzer、JProbe Profiler、JVisualVM 等。

06. 最后

以上内容着实是我那我时不时面试的内容之一,通过一系列的间题考察 Java 守护多多线程 员对 Jvm 的理解。

比如我通常会问面试者,Java 中处在内存泄漏吗?大每段人都有回答处在,接着我会问愿因着我能 写有有另两个守护多多线程 让内存泄漏,我能 为什写?大每段守护多多线程 员就回答不上来了。

愿因着面试者不能回答后面 的间题,我会接着和面试者聊聊,内存泄漏和内存溢出亲戚大伙之间与否处在联系 、以及在日常工作中怎么才能 才能 处置写出内存泄漏的代码 、愿因着生产出現 Jvm 相关间题时,排查间题的思路和步骤等等。

那些间题在我的博客中都有答案,早些年写了一系列关于 Jvm 的文章,亲戚大伙愿因着感兴趣的话接下来继续去阅读,http://www.ityouknow.com/java.html。

愿因着亲戚大伙着实在手机上看着更方便,不能关注:Java 极客技术公号,愿因着输出了或多或少 JVM 文章,我博客中的 Jvm 系列文章也都有推送到这种公号中。

关注一下又后该怀孕

参考出处:

https://lovoedu.gitee.io/javablog/2017/08/27/20170827/

https://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/index.html