Android内存管理(11)*常见JVM回收机制「Java进程内存堆分代,JVM分代回收内存,三种垃圾回收器」
参考:
http://www.blogjava.net/rosen/archive/2010/05/21/321575.html
1,Java进程内存堆分代:
典型的JVM根据generation(代)来进行GC。一个java程序内存堆有下面几个代:
- young generation (年轻代)
- tenured generation (老年代)
- permanent generation (永久代, perm gen),perm gen(或称Non-Heap 非堆)是个异类,稍后会讲到。注意,heap空间不包括perm gen。它是JVM用来存储无法在Java语言级描述的对象,这些对象分别是类和方法数据(与class loader有关)以及interned strings(字符串驻留)。一般32位OS下perm gen默认64m,可通过参数-XX:MaxPermSize=n指定。文献 : JVM Memory Structure
Heap中各generation空间是如何划分的?
通过JVM的-Xmx=n参数可指定最大heap空间,而-Xms=n
则是指定
最小heap空间。
在JVM初始化的时候,如果最小heap空间小于最大heap空间的话,JVM会把未用到的空间标注为Virtual。
除了这两个参数还有-XX:MinHeapFreeRatio=n和 -XX:MaxHeapFreeRatio=n来分别控制最大、最小的剩余空间与活动对象之比例。
在32位Solaris SPARC操作系统下,默认值如下,在32位windows xp下,默认值也差不多。
参数 |
默认值 |
MinHeapFreeRatio |
40 |
MaxHeapFreeRatio |
70 |
-Xms |
3670k |
-Xmx |
64m |
由于tenured generation的major collection较慢,所以tenured generation空间小于young generation的话,会造成频繁的major collection,影响效率。Server JVM默认的young generation和tenured generation空间比例为1:2,也就是说young generation的eden和survivor空间之和是整个heap(当然不包括perm gen)的三分之一,该比例可以通过-XX:NewRatio=n参数来控制,而Client JVM默认的-XX:NewRatio是8。至于调整young generation空间大小的NewSize=n和MaxNewSize=n参数就不讲了,请参考后面的资料。
2,JVM分代回收内存:
- 次回收
绝大多数的对象都在young generation被分配,也在young generation被收回,当young generation的空间被填满,GC会进行minor collection(次回收),这次回收不涉及到heap中的其他generation,minor collection根据weak generational hypothesis(弱年代假设)来假设young generation中大量的对象都是垃圾需要回收,minor collection的过程会非常快。
- 主回收
young generation中未被回收的对象被转移到tenured generation,然而tenured generation也会被填满,最终触发major collection(主回收),这次回收针对整个heap,由于涉及到大量对象,所以比minor collection慢得多。
3,三种垃圾回收器
- throughput collector,用来做并行young generation回收,由参数-XX:+UseParallelGC启动
- concurrent low pause collector,用来做tenured generation并发回收,由参数-XX:+UseConcMarkSweepGC启动
- incremental low pause collector,可以认为是默认的垃圾回收器。
不建议直接使用某种垃圾回收器,最好让JVM自己决断,除非自己有足够的把握。