Open ditunes opened 8 years ago
从GC ROOT 做为起始点,并从这些节点的引用出发进行搜索,其经过的路径称为Reference Chain,路径上可达的对象都表示存活对象,而那些不可达的对象则需要被回收
GC ROOT
Reference Chain
* 虚拟机栈中的栈帧存储的本地变量表所指向的对象。(方法正在执行时候局部变量所指向的对象) * 方法区中类静态属性引用的对象(静态变量指向的对象) * 方法区中的常量引用对象(final) * 本地方法栈中native method 引用的对象。 * 在Minor gc时候old代对象也将成为gc root,其指向的位于young代对象将不会被回收。
强引用
软引用(soft reference)
弱引用(weak reference)
虚引用(virtual reference)
总之对象是否被回收,需要考虑从gc root出发能否通过引用搜寻到该对象,而且还需要考虑引用的类型,并针对引用类型决定是否回收对象。
标记需要回收的对象,并使存活对象往内存一端移动,逐步填充生命周期结束的对象的空间。
标记生命周期结束的对象,并将其移除,很容易造成空间碎片化,使得内存利用率低,而且标记与清除效率不高。
很容易造成空间碎片化,使得内存利用率低,而且标记与清除效率不高
倘若将内存分为AB两块,A存放对象,当执行垃圾回收时,把存活对象拷贝到B,最后将A空间清除,使得空间回收效率高,没有碎片化出现。但是有一部分的内存空间会处于闲置状态,如前面的B空间,而且频繁复制会堆性能产生较大影响。分代收集法就是基于这个算法做了进一步扩展。
使得空间回收效率高,没有碎片化出现。但是有一部分的内存空间会处于闲置状态,如前面的B空间,而且频繁复制会堆性能产生较大影响
当前虚拟机根据对象生命周期长短不同的特点划分了不同意义的内存区域:
Young Generation
Minor gc
major gc
old generation
card table(卡表)
记录老年代对象字段引用的新生代对象地址,以及是否为脏的标记
full gc
PermSize
MaxPermSize
OOM(OutOfMemoryError "PermGen space")
扩展资料 Metaspace in Java 8 Java永久代去哪儿了 Java 8: From PermGen to Metaspace
如何识别对象已死?
引用计算算法
根搜索算法(JVM 的识别算法)
算法
从![1466491720059](https://cloud.githubusercontent.com/assets/19986112/16438861/a01e7d0e-3de5-11e6-82ce-a807bc044d81.png)
GC ROOT
做为起始点,并从这些节点的引用出发进行搜索,其经过的路径称为Reference Chain
,路径上可达的对象都表示存活对象,而那些不可达的对象则需要被回收什么是GC ROOT ?
并不是所有被引用的对象都不可回收,还需要看引用的类型!
强引用
:Object o = new Object() 只有在强引用不存在的时候该对象才会被垃圾回收器回收。软引用(soft reference)
:只有在内存溢出抛出异常之前的时候,被列入回收范围,并在第二次垃圾回收的时候进行回收。如果内存还是不够则抛出异常。(抛出内存溢出异常前会被回收)弱引用(weak reference)
:比软引用更弱,当不存在强引用的时候,则会在下一次垃圾回收的时候就会被回收。(执行垃圾回收时被回收)虚引用(virtual reference)
:无法通过虚引用获取对象,对象是否有虚引用存在,并不影响其生命周期,设置虚引用的目的是为了得到对象回收后的通知。(纯粹只是为了监听对象被回收事件)总之对象是否被回收,需要考虑从gc root出发能否通过引用搜寻到该对象,而且还需要考虑引用的类型,并针对引用类型决定是否回收对象。
内存回收机制
标记-整理法(Mark-Compact)
标记需要回收的对象,并使存活对象往内存一端移动,逐步填充生命周期结束的对象的空间。
标记-清除法(Mark-sweep)
标记生命周期结束的对象,并将其移除,
很容易造成空间碎片化,使得内存利用率低,而且标记与清除效率不高
。复制算法(Copying)
倘若将内存分为AB两块,A存放对象,当执行垃圾回收时,把存活对象拷贝到B,最后将A空间清除,
使得空间回收效率高,没有碎片化出现。但是有一部分的内存空间会处于闲置状态,如前面的B空间,而且频繁复制会堆性能产生较大影响
。分代收集法就是基于这个算法做了进一步扩展。分代收集法(Generation Collection)
当前虚拟机根据对象生命周期长短不同的特点划分了不同意义的内存区域:
分代的含义
Young Generation(年轻代)
Young Generation
对象生命周期较短,很快将会被垃圾回收器回收。Minor gc
执行该区域的垃圾回收.old Generation(老年代)
Young Generation
长时间存在(可设定阀值)的对象将会被放入该区域。或者在Young Generation
空间已满且经过垃圾回收后仍然无法满足新对象的空间需求的时候,Young Generation
对象将被移入老年代。major gc
.old generation
有一块空间称为card table(卡表)
,其中每512byte都被称为一个卡,卡表将记录老年代对象字段引用的新生代对象地址,以及是否为脏的标记
。jvm存在写屏障的功能,当修改了对象的某个引用的时候,就会先执行一段修改卡表的代码将该卡标记为脏(jvm在编译时期会在更新引用的代码后植入该屏障机制代码),其表示可能老年代的对象指向了新的年轻代数据。这样当进行minor gc的时候就可以不用扫描整个老年代(为了确定哪些新生代对象被引用,完全扫描空间较大的老年代,是非常耗费性能的),只需要扫描卡表脏数据即可知道该新生代对象是否需要被保留。permanent generation(永久代)or metaspace (元空间)
full gc
PermSize
andMaxPermSize
JVM 参数将失效。主要是因为OOM(OutOfMemoryError "PermGen space")
异常若使用用metaspace则会自动根据需要进行扩展,甚至可以将整个内存空间和swap区域占满。