Sun Java HotSpot™ Virtual Machine内存模型与垃圾回收

分代收集(Generational Collecting)
基于对对象生命周期分析后得出的垃圾回收算法,把对象分为年轻代、年老代、持久代,对不同生命周期的对象使用不同的算法进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法。


Sun JVM
内存区域分布图


1
Young(年轻代)
Young
被划分为三个区间,Eden区和两个大小严格相同的Survivor区,其中Survivor区,在某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用。在Young区间变满的时候,Minor GC就会将存活的对象移到空闲的Survivor区中,根据JVM的策略,在经过几次Minor GC后,任然存活于Survivor区的对象将被移动到Tenured中。

2
Tenured(年老代)
Tenured
主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后,对象就会被转移到Tenured。一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。

3
Perm(持久代)
Perm
主要保存classmethodfiled等对象,这部分的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到应用服务器的热部署时,有时候会遇到java.lang.OutOfMemoryError: PermGen space 的错误,造成这个错误的很大原因就有可能是每次热部署后,旧的class没有被卸载掉,这样就造成了大量的class对象保存在了Perm中,这种情况下一般重新启动应用服务器可以解决问题,或者通过-XX:MaxPermSize=<N> 将持久代大小设大点。

GC类型
大略上分以下2
1
Minor GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就好触发Minor GCEden区清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后再整理Survivor的两个区。

2
Full GC
对整个堆进行整理,包括YoungTenured以及PermFull GCMinor GC要慢,因此应该尽可能减少Full GC。以下几种原因可能导致Full GC

  • TenuredPerm被写满
  • System.gc被显示调用
  • 上一次GC后堆空间分配策略动态调整 



JVM调优参数
JVM
提供了相应的参数来对内存大小、垃圾回收算法进行配置。



Non-standard Java HotSpot VM Options
我在32Windows Server 2003系统8GB物理内存,JDK1.6下测试,最大可设置为1536M,再多JVM就跑不起来了。

-Xms1536M
设置JVM启动后堆的初始内存(这里配置的JVM堆空间只是YoungTenured
-Xmx1536M
设置JVM启动后堆的最大内存,一般在生产环境中把这两个参数设为相同值,避免在上一次GC后堆空间分配策略动态调整而引起Full GC
-Xss1M
设置每个线程的Java栈大小
-XX:NewRatio=2
设置TenuredYoung的比值为2:1,这样Eden+2*Survivor=1/3
堆内存
-XX:SurvivorRatio=8
设置Eden和一个Survivor的比值为8:1,这样一个Survivor就占Young区的1/10.
-XX:PermSize=64M    
设置持久代初始内存
-XX:MaxPermSize=128M 
设置持久代最大内存

详细配置选项见:http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#PerformanceTuning

垃圾收集器
JVM
给了三种选择:串行收集器、并行收集器、并发收集器。串行收集器对于处理大数据量的情况时性能太低,所以一般选择使用并行收集器和并发收集器。J2SE5.0以后JVM会根据当前系统配置进行判断(机器配置只要有2CPU和至少2GB的物理内存JVM将自动以-server模式运行)

1
)吞吐量优先的并行收集器,通过 -XX:+UseParallelGC 指定
2
)响应时间优先的并发收集器,主要是保证系统的响应时间,减少垃圾收集时的停顿时间。通过 -XX:+UseConcMarkSweepGC 指定。由于CMS GC是和应用并发执行的,因此需要耗费更多的CPU资源。

详细配置选项见:http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#BehavioralOptions

Sun JDK自带的图形监控和管理工具jconsole
通过Sun JDK自带的一个图形监控和管理工具jconsole能很容易的看到当前虚拟机中的内存状态,我使用的JDK版本是jdk1.6.0_18,这个工具从jdk1.5就有了

http://linliuwei.javaeye.com/blog/690192转贴

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值