zoukankan      html  css  js  c++  java
  • Java虚拟机的内存管理

    众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作.

    虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏.

    反而,某程度上,当出现内存泄漏,Debug会变得难度更大.

    所以,Java程序员,有必要去了解Java虚拟机对于内存的管理以及垃圾回收的机制.


    Java虚拟机是如何判断一个对象可以回收?

    当一个对象没有被任何其他所引用时,这个对象被Java虚拟机视为可回收.

    早起的虚拟机,使用引用计数的方法判断对象是否可回收.这个方法的好处是简单和效率高,却难以解决循环引用的问题.

    现在主流的Java虚拟机都是使用可达性的分析对象是否可回收.从若干Root节点开始遍历,所有从Root节点能到达的对象,都是存活对象.

    反之,其他对象就是可回收对象.可以想象,这是有若干个根节点的图,用图论术语就是判断每个节点的可达性.

    强引用,软引用,弱引用,虚引用都是什么?

    强引用Strong Reference就是平时最常见的,不加任何修饰的对象实例化,得到的都是强引用.

    软引用Soft Reference,软引用的对象,当Java虚拟机垃圾回收时出现空间不足的情况,软引用的对象就会被回收.

    弱引用Weak Reference,弱引用的对象,当Java虚拟机下一次垃圾回收时,无论如何都会被回收.

    虚引用Phantom Reference,虚引用的对象任何一个时刻都不能取得其对象的实例.虚引用的使用在于跟踪对象的生死存亡,当虚引用被垃圾回收时,会收到一个系统通知.

    垃圾回收算法都有哪些?

    1.标记清除,顾名思义就是标记和清除两个阶段.这个算法的致命弱点是,会产生大量的内存碎片,导致后期即使有足够的内存空间也无法分配大的连续的内存空间.

    2.复制算法,是把内存空间分成大小相等的两个区域,每次只使用其中一个区域.每次内存回收,都会把存活的对象复制到另外一个区域.

      这个算法虽然解决了内存碎片的问题,但是是以内存缩小原来的一半为代价.

      复制算法也常用在新生代的垃圾回收.因为大多数的对象都是朝生夕死的,不会存活过下一轮的垃圾回收.所以实际上并没有必要按照1:1的比例来划分内存空间.

      现实情况,内存被划分为一个较大的eden区和两个较小的survivor区.HotSpot虚拟机的eden:survivor:survivor=8:1:1.

      每次都会使用eden和其中一个survivor用来分配内存,当垃圾回收时会把存活的对象复制到另外一个survivor区.

      当出现survivor的内存不足时,会动用老年代的内存空间.老年代起的是一个担保的作用.

    3.标记整理算法.把存活的对象都标记出来,再移动到内存空间的一端,把端边界以外的内存空间都清除释放.老年代一般采用标记整理算法.

    4.分代收集算法.一般把内存空间分成老年代和新生代,不同的区域根据对象存活的周期和特点,使用合适的垃圾回收算法.

       新生代使用复制算法.老年代使用标记清除或者标记整理算法.

    Java程序会在什么时候执行垃圾回收呢?

    答案是,安全区域(Safe Region),指在一端代码片段之中,引用关系不会发生变化,在这个区域任意地方开始垃圾回收都是安全的.

    当线程执行到安全区域时,会首先标识自己已经进入了安全区域.

    当线程要离开安全区域时,它要检查系统是否已经完成了根节点枚举(或整个垃圾回收过程),如果完成那线程就继续执行,否则必须等到可以离开安全区域的信号为止.

    让所有执行线程都停顿下来到达最近的安全区域,有两种方案:

    1.抢占式中断(Preemptive Suspension).在垃圾回收发生时,首先把所有线程都全部中断,没有到达安全区域的线程,就恢复线程让它运行到最近的安全区域上.

       现在,几乎没有Java虚拟机是使用抢占式中断,来暂停所有线程从而执行垃圾回收.

    2.主动式中断(Voluntary Suspension).当准备执行垃圾回收时,会设置一个标志位,表示要开始垃圾回收了.所有线程都会在安全区域处轮询这个标志位.

       当发现这个标志位被设置后,线程会暂停自己.

  • 相关阅读:
    svn 巧用,如果遇到问题解决不了,而上一个版本可以正常使用,则可以查记录
    Fastadmin 后台编辑,或者添加的时候,出现的问题
    Fastadmin 写关联命名时,最好前后台用同一个model,方便管理(会出现命名空间问题)
    python笔记(一)基础一
    服务器端解决跨域
    支付宝的pc端配置
    解决svn update 产生Node remains in conflict的问题
    CentOS7使用firewalld打开关闭防火墙与端口
    腾讯云Centos7下启用端口防火墙
    Centos查看端口占用情况和开启端口命令
  • 原文地址:https://www.cnblogs.com/wingyip/p/4491419.html
Copyright © 2011-2022 走看看