java垃圾回收

我们知道JVM内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。其中程序计数器、虚拟机栈、本地方法栈是私有的,随着线程而生,随着线程而亡,因此这几个区域的垃圾回收不需要考虑,因为方法结束或者线程结束时,内存自然就会被回收。但是堆区和方法区(java1.8中在元空间,还需要考虑么????)不一样,这部分是垃圾回收需要关注的地方。

那么问题来了,一直在说回收垃圾,怎么判断哪些对象是垃圾,哪些不能作为垃圾回收呢???

有两种方法:引用计数法和可达性分析算法

引用计数法:给对象设置引用计数,当一个对象被引用时,计数+1,否则-1。当对象的引用计数为0时,该对象就可以被回收。

优点:引用计数收集器可以很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。

缺点:无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0。

可达性分析算法:

从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用节点,无用的节点将会被判定是可回收的对象。

在Java语言中,可以作为GC Roots的对象包括以下几种(京东)

a)在虚拟机栈中引用的对象(栈帧中的本地变量表)

b)方法区中类静态属性引用的对象

c)方法区中常量引用的对象

d)本地方法栈中JNI(Native方法)引用的对象。

你可能感兴趣的:(java)