您的位置:首页 > 其它

知晓JVM系列(二):JVM内存管理机制与优化初探

2014-12-15 20:26 429 查看
1.GC初探:

JVM的堆内存是程序开发常用到一块可以自己操作的内存区域,我们经常使用new产生的实例都存放在这片区域。正因为这块区域的自由度极高,所以管理起来也是相当的麻烦,所以JVM才设计了这一个GC机制帮助程序员进行内存管理,减少程序员手动的去管理内存带来的不必要的麻烦,提高内存使用效率和安全性。

JVM内存大小:限制于实际的最大物理内存,其限制因素跟其寄宿的操作系统的位数有关。JVM堆内存的初始分配由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由 -Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆 直到-Xms的最小限制

JVM堆内存结构如下:





JVM内存分配方式:

1、对象优先在EDEN分配
2、大对象直接进入老年代

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

4、适龄对象也可能进入老年代:动态对象年龄判断

GC(Garbage Collection)机制主要针对的是JVM中的堆内存,GC不会对非堆内存进行清理和回收。GC的回收内存机制是根据JVM堆内存模型来设计的,而整个堆内存模型的空间分配是满足对象的生命周期模型的。所以GC机制主要操作的内存区域有Eden
pool、survivor from、survivor to、Tenured这四块内存区域,Eden与survivor同属于一个代区:Youth generation ,Tenured 属于Old generation。

2.常见GC算法
1. 引用计数(Reference Counting)
比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。

2. 标记-清除(Mark-Sweep)

此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。

3. 复制(Copying)

此 算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理 正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍 内存空间。

4. 标记-整理(Mark-Compact)

此算法结合了“标记-清除”和“复 制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一 块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。

5. 增量收集(Incremental Collecting)

实施垃圾回收算法,即:在应用进行的同时进行垃圾回收。不知道什么原因JDK5.0中的收集器没有使用这种算法的。

6. 分代(Generational Collecting)

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

3.GC种类
1.单线程收集器(serial collector)
特点:使用单线程去完成所有的gc工作,没有线程间的通信,这种方式会相对高效,Client模式下默认。
2.并行收集器(parallel
collector或叫throughput collector )
特点:使用多线程的方式,利用多CUP来提高GC的效率主要以到达一定的吞吐量为目标,但是只在young
area使用使用多线程,Server模式下默认。
3.并发收集器(concurrent
collector或叫concurrent low pause collector)
特点:使用多线程的方式,利用多CUP来提高GC的效率并发完成大部分工作,使得gc
pause短。
4.GC类型
1. Scavenge GC (YGC)
一般情况下,当新对象生成,并且在Eden申请空间失败时,就好触发Scavenge GC,堆Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。

2. Full GC (FGC)

对整个堆进行整理,包括Young、Tenured和Perm。Full GC比Scavenge GC要慢,因此应该尽可能减少Full GC。有如下原因可能导致Full GC

5.衡量GC的指标(GC Metrics)

Throughput(吞吐量):所有没有花在执行GC上的时间占总运行时间的比重。

Pauses(暂停):当GC在运行时程序的暂停次数。或者是在感兴趣的暂停次数中,暂停的平均时长和最大时长。

Footprint(足迹?):当前使用的堆内存大小。

Promptness(及时性):不再使用的对象多久能被清除掉并释放其内存。

6.GC中对象的可触及状态

GC中对象的六种可触及状态

1.强可触及:对象可以从根结点不通过任何引用对象搜索到

2.软可触及:对象不是强可触及的,但是可以从根结点开始通过一个或多个(未被清除的)软引用对象触及

3.弱可触及:对象既不是强可触及也不是软可触及的,但是从根结点开始可以通过一个或多个弱引用对象触及

4.可复活的:对象既不是强可触及、软可触及,也不是弱可触及,但是仍然可能通过执行某些终结方法复活到这几种状态之一

5.影子可触及:不上以上任何可触及状态,也不能通过终结方法复活,并且它可以从根结点开始通过一个或多个影子引用对象触及(影子引用不会被垃圾收 集器清除,由 程序明确地清除)

6不可触及:就是已经准备回收的状态

7.GC过程



8.优化机制与操作
在Dos下使用java -X命令,查看具体配置命令



1.调整JVM堆内存各代空间比例与栈空间大小
(1). java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代

后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

-Xss128k: 设置每个线程的堆栈大小。

(2).java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为

1:4,年轻代占整个堆栈的1/5

-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个

Survivor区占整个年轻代的1/6

-XX:MaxPermSize=16m:设置持久代大小为16m。

-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代

比较多的应用,可以提高效率。

2.根据应用规模选择GC种类
(3). java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用

串行收集。

-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

(4).java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。

(5).java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100

-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。

(6).java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy

-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最

低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。

-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
(7).Incremental mode
-XX:+CMSIncrementalMode default: disabled 启动i-CMS模式(must with -XX:+UseConcMarkSweepGC)
-XX:+CMSIncrementalPacing default: disabled 提供自动校正功能

-XX:CMSIncrementalDutyCycle=<N> default: 50 启动CMS的上线

-XX:CMSIncrementalDutyCycleMin=<N> default: 10 启动CMS的下线

-XX:CMSIncrementalSafetyFactor=<N> default: 10 用来计算循环次数

-XX:CMSIncrementalOffset=<N> default: 0 最小循环次数(This is the percentage (0-100) by which the incremental mode duty

cycle is shifted to the right within the period between minor collections.)

-XX:CMSExpAvgFactor=<N> default: 25 提供一个指导收集数
3.调整GC清理的时间间隔
-XX:+UseParNewGC此命令可以加快minor收集时间。
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC此命令可以加快major收集时间
4.根据具体情况选择GC的算法
5.垃圾回收统计信息
-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

注:在java -X中并没有-XX命令,此时用 java -verbose:gc -XX:+PrintGCDetails

6.JVM运行模式选择:

(1).java -client

(2).java -server

7.常用监测工具

jconsole JDK自带的内存监测工具,路径jdk bin目录下jconsole.exe,双击可运行。

jvisualvm JDK自带的监测工具,路径jdk bin目录下jvisualvm .exe,双击可运行。

jvmstat jvmstat是图形版的jstat,由Java 官方提供,目前最新版本为3.0。

YourKit Java Profiler YourKit 是一个用于分析Java 与.NET 应用程序的智能工具,YourKit Java Profiler 已经被IT
专业人士与分析师

公认为最好的分析工具。通过YourKit 技术解决方案可以以非常高的的专业水平分析出CPU 与内存使用情况。

JProfiler 收费的工具,但是到处都有破解办法。安装好以后按照配置调试的方式配置好一个本地的session即可运行。

jinfo 可以从一个给定的java进程或core文件或远程debug服务器上获取java配置信息。包括java系统属性及JVM参数(command line flags)。

jmap 观察运行中的jvm物理内存的占用情况。

jps列出所有的jvm实例

jvmtop 一个轻量级的控制台程序用来监控机器上运行的所有 Java 虚拟机。

jstack 观察jvm中当前所有线程的运行情况和线程当前状态

jstat JVM监测工具(Java Virtual Machine Statistics Monitoring Tool)。利用了JVM内建的指令对Java应用程序的资源和性能进行实

时的命令行的监控,包括各种堆和非堆的大小及其内存使用量、classloader、compiler、垃圾回收状况等。

Java api方式监测jre中提供了一些查看运行中的JVM内部信息的api,这些api包含在java.lang.management包中,此包中的接口

是在jdk 5中引入的,所以只有在jdk 5及其以上版本中才能通过这种方式访问这些信息。

参考文章:
/article/5834919.html
http://blog.csdn.net/ithomer/article/details/6252552
http://hi.baidu.com/qust409xls/item/d013eb1126f0c30f8ebde4a6
http://blog.chinaunix.net/uid-7374279-id-4489100.html
http://zhangjiangxing-gmail-com.iteye.com/blog/1048832
http://blog.csdn.net/kobejayandy/article/details/8496663
http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html
http://wenku.baidu.com/view/de4b06a8dd3383c4bb4cd235.html
/article/6054109.html
/article/5834919.html
/article/7813656.html
/article/5834923.html
/article/4027028.html
http://developer.51cto.com/art/201009/227512.htm
/article/3528975.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: