微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

深解JVM 3-内存调优

前言

JVM基本概念

深解JVM 1-Java虚拟机基本原理 - chch213 - 博客园 (cnblogs.com)

JVM内存结构

深解JVM 2-内存结构 - chch213 - 博客园 (cnblogs.com)

前面我们讲了JVM一些常识性的东西,以及垃圾回收机制主要针对的堆的内存回收。本文我们主要介绍下JVM调优的一些基本知识。

 

下图文JVM的内存模型

 

从图中我们可以看到,

1、堆内存结构,年轻代(YoungGen),年老代(Old Memory),及持久代(Perm,在Java8中被取消,我们不做深入介绍)。

2、垃圾回收GC,分为2种,一是Minor GC,可以可以称为YGC,即年轻代GC,当Eden区,还有一种称为Major GC,又称为FullGC。

3、GC原理:

我们可以看到年轻代包括Eden区(对象刚被new出来的时候,放到该区),S0和S1,是幸存者1区和幸存者2区,从名字可以看出,是当发生YGC,没有被任何其他对象所引用的对象将会从内存中被清除,还被其他对象引用的则放到幸存者区。当发生多次YGC,在S0、S1区多次没有被清楚的对象,则会被移到老年代区域。当老年代区域被占满的时候,则会发送FullGC。

无论是YGC或是FullGC,都会导致stop-the-world,即整个程序停止一些事务的处理,只有GC进程允许以进行垃圾回收,因此如果垃圾回收时间较长,部分web或socket程序,当终端连接的时候会报connetTimeOut或readTimeOut异常,

4、从JVM调优的角度来看,我们应该尽量避免发生YGC或FullGC,或者使得YGC和FullGC的时间足够的短。

 

JVM调优详解

一、对JVM内存的系统级的调优主要目的是减少GC的频率和Full GC的次数,过多的GC和Full GC是会占用很多的系统资源(主要是cpu),影响系统的吞吐量。特别要关注Full GC,因为它会对整个堆进行整理,Full GC一般由以下几个原因导致:

1、老年代空间不足
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在老年代创建对象

2、持久代;空间不足
增大持久代空间,避免太多静态对象

3、System.gc()被显示调用
垃圾回收不要手动触发,尽量依靠JVM自身的机制

二、调优手段
调优手段主要是通过控制堆内存的各个部分的比例和GC策略来实现,下面来看看各部分比例不良设置会导致什么后果:

1、新生代设置过小
新生代GC次数非常频繁,增大系统消耗
导致大对象直接进入老年代,占据了老年代剩余空间,诱发Full GC
2、新生代设置过大
新生代设置过大会导致老年代过小,从而诱发Full GC
新生代GC耗时大幅度增加
一般来说新生代占整个堆1/3比较合适

3、保留空间Survivor设置过小
导致对象从使用空间eden直接到达老年代,降低了在新生代的存活时间

4、保留空间Survivor设置过大
导致eden过小,增加了GC频率

另外,通过-XX:MaxTenuringThreshold=n来控制新生代存活时间,尽量让对象在新生代被回收

JVM提供两种较为简单的GC策略的设置方式

(1)吞吐量优先
JVM以吞吐量为指标,自行选择相应的GC策略及控制新生代与老年代的大小比例,来达到吞吐量指标。这个值可由-XX:GCTimeRatio=n来设置。

(2)暂停时间优先
JVM以暂停时间为指标,自行选择相应的GC策略及控制新生代和老年代的大小比例,尽量保证每次GC造成的应用停止时间都在指定的数值范围内完成,这个值可由-XX:MaxGCPauseRatio=n来设置。

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐