JVM深入学习笔记四:JVM垃圾收集和内存分配
2014-10-08 20:02
543 查看
1. 垃圾判断算法
引用计数法, 给对象添加引用计数器,每有一个引用则+1, 没有则-1,为0为已死。python就是使用这种算法。 但是不能解决循环引用的问题。
根搜索算法。 从根开始向下搜索,如果有对象到根不可达则为死对象。 HopSpot使用的是这种算法。
这里的根可以是栈中的引用对象, 方法区常量的引用对象,方法区静态属性的引用对象,JNI的引用对象。
两次标记。 虚拟机在回收对象时要做两次标记才会真的回收。无根的时候是一次,执行了finallise方法的时候会再标记一次。标记两次后,再执行到finalise方法就会回收对象。
回收方法区。 会回收常量池和做类卸载,可以使用-verbose:class来查看类的装载及卸载情况。
2. 垃圾收集算法
标记清除算法。
标记出所有需要回收的对象,标记完成后清除所有标记了的对象。 问题在于:效率不高,空间上会产生大量的碎片
复制算法。
把内存分为两个等块, 每次使用一块,当这一块满了之后把存活的对象转移到另外一块上去,然后清空这一块。 这样有点空间浪费。
HopSpot 的新生代基于这个算法,把内存分为了一个较大的Eden空间和两个较小的Survior空间。每次使用Eden和一个Survior,GC的时候把他们两个中存活的对象拷贝到另一个S空间,清空Eden和S1, 如果S2不够大,则会把对象复制到老生代。
标记整理 当系统运行比较久后,对象的存活率比较高,复制算法就会有很多的复制操作,效率将会变低。因此对于老生代,使用标记-真理算法。
把存活对象标记并向一个方向清理,完成后把边界外的统一清空。
基于复制算法的新生代,标记整理的老生代,也就是分代收集的算法了。新生代GC(Minor GC), 老生代GC(Major GC)
3. 垃圾收集器
有很多种,主要是针对问题的不同,有单线程的,为了减少停顿时间的,还有使用不同算法实现的。 目前最新的叫做G1
4. 内存分配
优先在Eden上分配
参数:
-Xmn:新生代大小
-XX:Sur... : Eden和S的比
-XX:+Print.. : 打印详细的GC信息
代码:
大概的过程是,前三个对象分配在Eden上,当分配第四个的时候发现Eden不够大, 因此做GC,做GC的时候发现对象都比S大,因此分配到老生代去了。
最后将是Eden上对象4, 老生代上有1,2,3
大对象直接进入老生代
上面那个例子,加入参数-XX:PertenureSizeThreshold参数指定大于这个值的对象会直接进入老生代。
长期存活的对象将进入老生代
每熬过一次MinorGC年龄增加一岁, -XX:MaxTenuringThreshold设置几岁的对象进入老生代。
大于平均值的进入老生代
当处于一个年龄的对象达到了数目的一半以上,那么比这个年龄大的将会进入到老生代。
引用计数法, 给对象添加引用计数器,每有一个引用则+1, 没有则-1,为0为已死。python就是使用这种算法。 但是不能解决循环引用的问题。
根搜索算法。 从根开始向下搜索,如果有对象到根不可达则为死对象。 HopSpot使用的是这种算法。
这里的根可以是栈中的引用对象, 方法区常量的引用对象,方法区静态属性的引用对象,JNI的引用对象。
两次标记。 虚拟机在回收对象时要做两次标记才会真的回收。无根的时候是一次,执行了finallise方法的时候会再标记一次。标记两次后,再执行到finalise方法就会回收对象。
回收方法区。 会回收常量池和做类卸载,可以使用-verbose:class来查看类的装载及卸载情况。
2. 垃圾收集算法
标记清除算法。
标记出所有需要回收的对象,标记完成后清除所有标记了的对象。 问题在于:效率不高,空间上会产生大量的碎片
复制算法。
把内存分为两个等块, 每次使用一块,当这一块满了之后把存活的对象转移到另外一块上去,然后清空这一块。 这样有点空间浪费。
HopSpot 的新生代基于这个算法,把内存分为了一个较大的Eden空间和两个较小的Survior空间。每次使用Eden和一个Survior,GC的时候把他们两个中存活的对象拷贝到另一个S空间,清空Eden和S1, 如果S2不够大,则会把对象复制到老生代。
标记整理 当系统运行比较久后,对象的存活率比较高,复制算法就会有很多的复制操作,效率将会变低。因此对于老生代,使用标记-真理算法。
把存活对象标记并向一个方向清理,完成后把边界外的统一清空。
基于复制算法的新生代,标记整理的老生代,也就是分代收集的算法了。新生代GC(Minor GC), 老生代GC(Major GC)
3. 垃圾收集器
有很多种,主要是针对问题的不同,有单线程的,为了减少停顿时间的,还有使用不同算法实现的。 目前最新的叫做G1
4. 内存分配
优先在Eden上分配
参数:
-verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:SurvivorRatio=8 -XX:+PrintGCDetails-verbose:gc 打印GC的信息
-Xmn:新生代大小
-XX:Sur... : Eden和S的比
-XX:+Print.. : 打印详细的GC信息
代码:
public class MemoryAllocation { private static final int MB = 1024 * 1024; public static void main(String[] args) { byte[] allocation1 = new byte[2 * MB]; byte[] allocation2 = new byte[2 * MB]; byte[] allocation3 = new byte[2 * MB]; byte[] allocation4 = new byte[4 * MB]; } }输出:
<span style="color:#ff6666;">[GC [DefNew: 6487K->148K(9216K), 0.0037546 secs] 6487K->6292K(19456K), 0.0037798 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap</span> def new generation total 9216K, used 4572K [0x35c10000, 0x36610000, 0x36610000) <span style="color:#ff6666;"> eden space 8192K, 54% used [0x35c10000, 0x36061fa8, 0x36410000) from space 1024K, 14% used [0x36510000, 0x365352b8, 0x36610000) to space 1024K, 0% used [0x36410000, 0x36410000, 0x36510000)</span> tenured generation total 10240K, used 6144K [0x36610000, 0x37010000, 0x37010000) <span style="color:#ff6666;"> the space 10240K, 60% used [0x36610000, 0x36c10030, 0x36c10200, 0x37010000)</span> compacting perm gen total 12288K, used 378K [0x37010000, 0x37c10000, 0x3b010000) the space 12288K, 3% used [0x37010000, 0x3706e8a0, 0x3706ea00, 0x37c10000) ro space 10240K, 54% used [0x3b010000, 0x3b58ee00, 0x3b58ee00, 0x3ba10000) rw space 12288K, 55% used [0x3ba10000, 0x3c0b2800, 0x3c0b2800, 0x3c610000)
大概的过程是,前三个对象分配在Eden上,当分配第四个的时候发现Eden不够大, 因此做GC,做GC的时候发现对象都比S大,因此分配到老生代去了。
最后将是Eden上对象4, 老生代上有1,2,3
大对象直接进入老生代
上面那个例子,加入参数-XX:PertenureSizeThreshold参数指定大于这个值的对象会直接进入老生代。
长期存活的对象将进入老生代
每熬过一次MinorGC年龄增加一岁, -XX:MaxTenuringThreshold设置几岁的对象进入老生代。
大于平均值的进入老生代
当处于一个年龄的对象达到了数目的一半以上,那么比这个年龄大的将会进入到老生代。
相关文章推荐
- 深入理解JVM学习笔记-垃圾收集器和内存分配策略
- 深入理解JVM虚拟机学习笔记(二)垃圾收集器与垃圾收集算法
- 深入理解JVM笔记二---垃圾收集器及内存分配策略
- jvm-垃圾收集器和内存分配策略(这只是一些关键点,并没有深入理解)
- jvm学习笔记(5)垃圾收集器介绍
- 读 - 深入理解java虚拟机 - 笔记(六-4) - 垃圾收集器和内存分配策略(3章)-内存分配
- Java虚拟机学习笔记(二)——垃圾收集与内存分配
- 深入理解JVM阅读笔记-垃圾收集器1
- JVM学习笔记三:垃圾收集器与内存分配策略
- JVM学习笔记3-垃圾收集算法
- JVM学习笔记2 垃圾收集器与内存分配策略
- 学习JVM(垃圾收集和内存分配)
- 读 - 深入理解java虚拟机 - 笔记(六-1) - 垃圾收集器和内存分配策略(3章)-对象已死吗
- JAVA程序员养成计划之JVM学习笔记(2)-垃圾收集管理
- JVM 学习笔记20180206之三 垃圾收集器
- 【Java】深入理解JVM学习笔记(三) —— GC收集器和内存分配
- JVM垃圾收集算法学习笔记
- JVM学习笔记二 :垃圾收集的过程分析Eden->Survivor->Tenured
- 深入理解JVM阅读笔记-垃圾收集算法(字太多,不手打转载了)