java内存优化详解_jvm堆内存优化详解

在日常的运维工作中用到tomcat,都需要对tomcat中的jvm虚拟机进行优化,只有知道需要优化参数的具体用处,才能深刻体会优化jvm的意义所在。

在平常的工作中我们谈对jvm的优化,主要是针对java的堆内存的优化和垃圾回收机制的优化。

JVM堆内存示意图:

88180201a00f73cf320be001196020c9.png

JVM的堆内存的组成:

young generation:新生代

eden:伊甸园区

surived:存活区

其中存活区有2个,第1个为S0,第2个为S1

old generation:老年代

permanent generation:持久代

堆内存相关参数详解:

-Xms:初始化堆内存大小,不包括持久代的内存,默认为物理内存的1/64,不会超过1G

-Xmx:最大堆内存大小,不包括持久代内存,默认为物理内存的1/4

-Xmn:新生代内存大小,默认值为Xmx的3/8,老年代内存则为5/8

-XX:NewRatio:指定新生代与老生代的内存的比值,默认值为2

-XX:SurvivorRatio:eden和2个存活区内存的比值,默认值为8

-XX:PermSize:初始化时持久代内存的大小

-XX:MaxPermSize:最大持久代内存的大小

建议:

1.一般建议Xms等于Xmx,好处是避免每次gc后,调整堆的大小,减少系统内存分配开销

2.建议-XX:PermSize和-XX:MaxPermSize的值相同,因为永久代大小的调整也会导致堆内存需要触发FGC; 一般设置为128M就足够;

栈内存相关参数详解:

-Xss:指定线程的最大栈空间,默认为1M

jvm垃圾收集算法:

1.引用计数算法

每个对象有一个引用计数属性,新增一个引用计数加1,引用释放时计数减1,计数为0可以回收。

此方法简单,无法解决对象相互循环引用的问题。还有一个问题是如何解决精准计数。

2.根搜索算法(GC Roots)

从GC Roots开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链时,则证明此对象是不可用的。

jvm垃圾回收算法:

1.复制算法(Copying)

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

3.标记整理压缩算法(Mark-Compac)

复制算法:

采用从根集合扫描,并将存活对象复制到一块新的没有使用过的空间中,成本是需要一块内存交换空间

此算法用于新生代内存回收,从E区复制到S0或者S1

标记清除算法:

采用从根集合扫描,对存活的对象标记,标记完毕后再扫描整个空间中未被标记的对象,进行回收。

优点:在存活对象较多的情况下极为高效

缺点:标记清除算法直接回收不存活的对象,会造成内存碎片

标记整理压缩算法:

采用与标记清除一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象后,会将所有存活

对象往左端空闲空间移动,并更新对应的指针。此算法在标记清除的基础上,又进行了对象的移动。

优点:可以解决内存碎片问题

缺点:成本要比标记清除算法要高

垃圾回收名词解释:

1.串行回收(Serial)  --> gc单线程内存回收,会暂停所有用户线程,独占式回收

2.并行回收(Parallel)  --> 多个gc线程并行工作,会暂停所有用户线程,独占式回收

3.并发回收(CMS) --> gc线程和用户线程同时执行,不需要停顿用户线程(用户线程还是需要停顿,只是很短)

GC串行回收器(Serial回收器):

1.是一个单线程的收集器,只能使用一个CPU或一条线程去完成垃圾收集;在进行垃圾收集时,必须

暂停所有其它工作线程。直到收集完成。

2.缺点:Stop-the-World

3.优势:简单,对于单CPU的情况,由于没有多线程交互开销,反而更高效。

开启方法:

-XX:+UseSerialGC来开启

使用此参数后:新生代和老年代都采用Serial回收器进行垃圾回收

新生代使用复制算法

老年代使用标记压缩算法

GC并行回收器(ParNew回收器):

1. 并行回收也是独占式回收器,在收集过程中,应用程序会全部暂停。但由于并行回收器使用多线程

进行垃圾回收,因此在并发能力比较强的CPU上,它产生的停顿时间要短于串行回收器。而在单

CPU上或者并发能力较弱的系统中,回收效果不会比串行回收器好。

开启方法:

-XX:UserParNewGC

使用此参数后:新生代使用并行回收收集器,老年代使用串行收集器

-XX:ParallelGCThreads 可以指定线程数量,最好与CPU数量相当

新生代使用复制算法

新生代吞吐量优先回收器(Parallel Scavenge回收器):

1.吞吐量优先回收器:关注CPU吞吐量,即运行用户代码的时间/总时间,这种收集器能最高效率利用CPU。

开启方法:

-XX:UseParallelGC开启

使用此参数后:将使用Parallel Scavenge+Serial Old收集器组合回收垃圾,这也是Server模式下的默认值。

-XX:GCTimeRation 可以设置用户执行时间占总时间的比例,默认为99,即用1%时间进行垃圾收集

新生代使用复制算法

新生代吞吐量优先回收器(Parallel Scavenge回收器):老生代用Parallel Old算法

开启方法:

-XX:UseParallelOldGC开启

使用Parallel Scavenge和Parallel Old组合收集器进行收集

老年代使用标记整理算法

并发标记清除回收器(CMS回收器):

运作过程分为4个阶段:初始标记,并发标记,重新标记,并发清除

其中标记和重新标记两个阶段仍然需要Stop-The-World,其它过程中收集器和用户线程是一起工作的

启动方法:

-XX:ParallelCMSMarkSweepGC

使用此参数后:使用ParNew + CMS + Serial Old的组合进行内存回收。Serial Old作为CMS出现

“Concurrent Mode Failure”失败后的后备收集器使用。

其它参数:

-XX:ParallelCMSThreads 手工设置CMS的线程数量

-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后发出垃圾收集,默认为68%,仅在CMS收集器时有效。

-XX:CMSFullGCBeforeCompaction:设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与-XX:CMSInitiatingOccupancyFraction一起使用

GC性能监控指标:

吞吐量 --> 应用花在非GC上的时间百分比

CG负荷 --> 与吞吐量相反,指应用花在GC上的时间百分比

暂停时间 --> 应用花在GC stop-the-world的时间

GC频率 -->

一个交互式的应用要求暂停时间越少越好,非交互性应用,要求GC负荷越低越好

一个实时系统对暂停时间和GC负荷的要求都是越低越好

本文转自激情燃烧的岁月博客51CTO博客,原文链接http://blog.51cto.com/liuzhengwei521/1925056如需转载请自行联系原作者

weilovepan520

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值