JVM GC内存回收

JVM GC内存回收

有很多类似的名词,GC,垃圾回收,空间整理,内存回收。这些词基本都可以大概的描述我们接下来的内容。

有几个问题,要先提出,

  1. 为什么要回收内存?
  2. 哪些内存要回收?
  3. 什么时候回收?
  4. 怎么干?

  第一个很明显,因为空间不是无限的,当JVM可利用的内存空间越来越小,就会导致无法给新的对象分配内存,导致OOM

  第二个问题,哪些内存要回收,我们不能把正在使用的内存给回收了,那样会导致系统的异常。所以如果知道哪些内存需要回收,需要一些方法来确定。

比较通俗的说法就是已经“死”掉的对象,可以理解成是系统不再用了。

  这就出现了新问题,如何判断对象是否成活?

  引用计数法(Reference Counting)

  一种是 引用计数法(Reference Counting),概念是在对象中添加一个引用计数器,有引用的它的时候,计数器+1,引用失效,计数器-1;计数器为0就代表对象不可再被使用。

  看上去很简单,但是有很多问题情况要考虑,一个比较大的问题就是很难解决对象之间相互循环引用的问题,不是说无法解决,而是很难。

  可达性分析方法(Reachability Analysis)

  另一种是 可达性分析方法(Reachability Analysis),思路是通过一系列‘GC Roots’的根对象作为开始节点集,从节点开始根据引用关系向下搜索,搜索过程的路径称为‘引用链’(reference chain),如果对象到 roots没有任何引用链,就说明对象不可能被使用

  GC Roots的对象包含:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象,例如各个线程被调用的方法堆栈中使用的参数,局部变量,临时变量等。
  • 方法区中类静态属性引用的对象,例如JAVA类的引用类型静态变量
  • 方法区中常量引用的对象,例如字符串常量池里的引用。
  • 本地方法栈中JNI(Native方法)引用的对象。
  • Java虚拟机内部的引用。
  • 所有被同步锁(synchronized)持有的对象
  • 反映Java虚拟机内部情况的JMXBean,JVMTI中注册的回调,本地代码缓存等。

  第3个问题,什么时候回收,一般是GC收集器自己来决定的,因为实现GC功能的收集器很多,具体要看他们自己是什么时候执行。Coder即使触发GC,GC也不会立即执行。

  第4个问题,怎么干?

  从这里开始就会涉及到GC的一些算法理论,后面再说。简单来说,在GC之后,JVM就会有空闲可用的内存空间,如果还是没有足够的内存空间,那就会OOM。

 

JVM 垃圾收集算法

原文地址:https://www.cnblogs.com/dreamtaker/p/13346162.html