• JVM学习笔记(一):垃圾回收机制?原理?内存泄漏?内存溢出?


    面试中经常会被面试官问到关于JVM的知识,由于一直在大学的象牙塔中,也没有好好了解过其中的奥秘。

    觉得这一块也挺重要的,所以专门找了一些资料,学习了一下。

    1.什么是垃圾回收机制

      垃圾回收机制,也叫做GC。这可以说是java最强的特性之一,GC直击C++开发痛点,无需开发人员手动管理内存,只需要放肆的New即可。Java会自动回收过期的对象。

    但是很不幸,Java也存在内存泄漏。

    2.GC是如何判断可以回收的?

      GC有两种方式判断是否回收对象。一种是引用计数法,另一种是可达性分析。

     1.引用计数法

      引用计数法,就是一个对象,被引用一次,就+1,当引用数为0的时候,就说明该对象不再被引用,不再被需要,此时就会被GC回收,但是。。。。

    当A引用了B,B又引用了A,两个对象互相引用,那么这么两个对象永远不会被GC所回收。

     2.可达性分析

       可达性分析。从GC ROOTS开始向下搜索,搜索经过的路成为引用链,当一个对象到GC ROOTS无任何引用链可达时,证明该对象是不可用的。则判断对象可以进行回收 。

    引用链可以解决循环引用的的问题。

    GC ROOTS包括以下这么对象:

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

    3.什么是内存泄漏

      内存泄漏就是在程序运行中,已经用不到的对象,但是因为某种原因,躲过了上面两种回收检测机制,GC没有进行回收,从而该对象一直占用在内存中。

    偶尔的内存泄漏对程序不会有太大的影响,但是积少成多,不管多大的内存,迟早会被这些无用的对象耗尽内存,最终造成内存溢出

    可以说这是程序编码中的漏洞,程序的减分项。  

    4.什么时候会出现内存泄漏

      1.当一个长生命周期的对象引用了一个短生命周期的对象时,就会发生内存泄漏。比如下面的这段代码:

    1 public class LongLifeCycle(){
    2     public Object object;                   
    3     public void AMethod(){      
    4         object = new Object;
    5     }
    6 }

       比如这种情况,如果调用了Amethod()方法,就new了一个object的引用,但是我们也许仅仅只在这个方法中需要用到这个object对象;当这么方法结束时,我们就希望GC会将这个object回收。

    但是,类中全局的object对象一直持有着引用,所以GC并不会如我们希望的这样做。这么一个小小的object也许在小体量的程序中掀不起什么大浪,但是如果我们有百万级的用户,并且这个类是多例的。

    那么这就是一个大问题了。

      解决方法也很简单。就是将现在的全局变量写到方法中,变成局部变量就好了。这也算是一点点细节。。

      

      2.集合中的内存泄漏

      看了之后才发现,我一直以来都有着这样的错误。

      很多时候,在循环添加数据时,为了保证对象引用的不同,有些值我们不能定义在循环的外面。所以一旦集合对象(比如 HashMap、ArrayList 等)发生了泄漏,会连带着很多对象一起泄漏。

    ArrayList<Object> list = new ArrayList<>();
    for(int i=0;i<10;i++){
        Object object = new Object();
        list.add();
        object =null;    
    }

      这种时候我们创建了十个Object对象,每次循环中虽然释放了object对象。但是list中依然引用着object对象(虽然不是同一个object对象)所以GC不会进行回收,只有objext从list中移除,或list=null时;才会将这一串数据全部释放掉。所以在创建一些数据体量比较庞大的集合时,一定要多个心眼。看看是否会及时释放。

    4.内存泄漏和内存溢出

      内存泄漏和内存溢出,两者的概念是完全不一样的,但是他们有着一些关联。

      内存溢出(out of memory):当程序在申请内存时,没有足够的内存供其使用,就会出现out of memory

      内存泄漏(memory leak):当一个对象不在被使用,但是一直占据着一个内存时,就发生了一次内存泄漏,就像上面说的,偶尔一次泄漏可能不是什么问题。

    但是大量的泄漏就是程序弊病。内存泄露堆积后,无论多少内存,迟早会被占用光,内存泄漏是内存溢出的诱因之一

      

  • 相关阅读:
    转载: JS 中 new 操作符
    转载: js的值,对象,原型
    php setcookie(name, value, expires, path, domain, secure) 参数详解
    转载:js数组对象操作
    转载: js数组与 json 的区别
    转载: js的Prototype属性 解释及常用方法
    行人检测程序对接景区测试人数比对数据库切换时间不准确排查
    TSINGSEE青犀视频行人检测集成票务系统读取票务系统数据库为空的问题
    EasyWasmPlayer播放视频报错Uncaught (in promise)DOMException
    名胜景区部署TSINGSEE青犀视频监控具备哪些现实意义?
  • 原文地址:https://www.cnblogs.com/jinsheng1027/p/12036301.html
Copyright © 2020-2023  润新知