JVM——垃圾回收

2019-05-01  本文已影响0人  双核孤城

《深入理解Java虚拟机》学习笔记

垃圾回收,即回收不需要再使用的对象。

c中的垃圾回收主要是由程序员自己调用api进行回收,java中则是由虚拟机代劳。

什么样的对象可以被判定为垃圾?什么时候回收?怎样回收?带着问题学习一波。

区域划分

谈垃圾回收之前,先总结下垃圾回收的区域划分

垃圾回收主要作用域堆,堆被划分为新生代老年代

新生代又被分为,Eden,From survivor,To survivor

什么样的对象是垃圾

可以由引用计数法和可达性分析算法,一般采用后者

引用计数法

可达性分析法

引用之,强、软、弱、虚四大类

无论是引用计数法还是可达性分析法,都和引用有莫大关系,关于引用,因为回收策略和功能的不同,也有4类,如下:

何时回收

内存区域空间不足够的时候,会在安全点和安全区域进行垃圾回收

回收又分为minor gc和major gc,full gc

安全点

安全区域

如何回收

标记-清除法

首先标记出所有需要回收的对象,在标记完成后统一回收被标记的对象

缺点:效率低,空间利用率低

image

复制算法

把内存分为两部分,每次只是用其中一部分。当进行垃圾回收的时候,把一部分中的存活对象复制到另一部分中去

缺点:空间利用率低


image-20190421163714223

此收集算法适合新生代垃圾回收,JVM把内存区域分为Eden区域和两个Survivor区域,比例为Survivor:Survivor:Eden = 1:1:8

标记-整理算法

一般在老年代采用。把存活的对象标记并向一端移动,并清除掉端边界以外的内存

image-20190421164743511

分代收集算法

分代收集算法是以上几种算法的组合,根据不同内存区域的对象特点采用不同的回收策略。

内存分配与回收策略总结

对象优先在Eden分配

一般对象会在Eden区域分配,当Eden区域没有足够空间分配的时候,虚拟机发起一起minor gc

大对象直接进入老年代

需要大量连续内存空间的java对象直接进入老年代,如长字符串、数组

原因:Eden区域一般采用复制算法,而大对象的复制成本较高

长期存活的对象进入老年代

每个对象定义年龄计数器,没经过一次minor gc,对象年龄+1,年龄增加到一定程度,晋升到老年代

动态对象年龄判定

Survivor空间中相同年龄的所有对象的总大小大于Survivor空间的一般的时候,年龄大于或等于该年龄的对象晋升老年代

空间分配担保

minor gc前jvm会做一些检测,如下:

上一篇下一篇

猜你喜欢

热点阅读