第十九周

1、 简述JVM垃圾回收算法分类

常用的垃圾回收算法有如下四种:标记-清除、复制、标记-整理和分代收集。

标记-清除算法

从算法的名称上可以看出,这个算法分为两部分,标记和清除。首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。

这个算法简单,但是有两个缺点:一是标记和清除的效率不是很高;二是标记和清除后会产生很多的内存碎片,导致可用的内存空间不连续,当分配大对象的时候,没有足够的空间时不得不提前触发一次垃圾回收。

复制算法

这个算法将可用的内存空间分为大小相等的两块,每次只是用其中的一块,当这一块被用完的时候,就将还存活的对象复制到另一块中,然后把原已使用过的那一块内存空间一次回收掉。这个算法常用于新生代的垃圾回收。

复制算法解决了标记-清除算法的效率问题,以空间换时间,但是当存活对象非常多的时候,复制操作效率将会变低,而且每次只能使用一半的内存空间,利用率不高。

标记-整理算法

这个算法分为三部分:一是标记出所有需要被回收的对象;二是把所有存活的对象都向一端移动;三是把所有存活对象边界以外的内存空间都回收掉。

标记-整理算法解决了复制算法多复制效率低、空间利用率低的问题,同时也解决了内存碎片的问题。

分代收集算法

根据对象生存周期的不同将内存空间划分为不同的块,然后对不同的块使用不同的回收算法。一般把Java堆分为新生代和老年代,新生代中对象的存活周期短,只有少量存活的对象,所以可以使用复制算法,而老年代中对象存活时间长,而且对象比较多,所以可以采用标记-清除和标记-整理算法。

2、 叙述JVM常用的调优参数

-Xmx :堆的最大值 

-Xms :堆的最小值,即初始值                                   ##可以让xms=xmx

-XX:NewSize=1024MB :新生代初始大小

-XX:MaxNewSize=1024MB :新生代最大值

-XX:NewRatio=m :New和Old的比值

-Xmn=1024MB :新生代大小                          ##一般使用-Xmn来固定新生代大小

-XX:SurvivorRatio=m :Eden和Survivor的比值

-XX:TargetSurvivorRatio=n :minor GC后Survivor预期被占用的比例

-XX:+UseConcMarkSweepGC :新生代使用ParNew,老生代优先使用CMS,备用方式为Serial Old

-XX:+CMSFullGCsBeforeCompaction : 在多少次回收后执行一次内存碎片整理

-XX:+PrintTenuringDistribution :查看每次minor GC后年龄的分布和计算出来的TenuringThreshold

-XX:+PrintGC :输出GC简要信息

-XX:+PrintGCDetails :输出GC信息

-XX:+PrintGCTimeStamps :输出GC时间戳

-XX:+PrintGCApplicationStoppedTime :输出GC暂停时间

-Xlogg c:/gc.log        输出到文件

3、 JAVA进程发生OOM如何调优

最常见的OOM情况有以下三种:

•    java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。

•    java.lang.OutOfMemoryError: PermGen space ------>java永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize=64m -XX:MaxPermSize=256m的形式修改。另外,过多的常量尤其是字符串也会导致方法区溢出。

•    java.lang.StackOverflowError ------> 不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

OOM分析--heapdump

要dump堆的内存镜像,可以采用如下两种方式:

•    设置JVM参数-XX:+HeapDumpOnOutOfMemoryError,设定当发生OOM时自动dump出堆信息。不过该方法需要JDK5以上版本。

•    使用JDK自带的jmap命令。"jmap -dump:format=b,file=heap.bin "  其中pid可以通过jps获取。

dump堆内存信息后,需要对dump出的文件进行分析,从而找到OOM的原因。常用的工具有:

•    mat: eclipse memory analyzer, 基于eclipse RCP的内存分析工具。

•    jhat:JDK自带的java heap analyze tool,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等。

你可能感兴趣的:(第十九周)