简介

JVM优化主要是内存分配优化和GC策略优化。

内存分配优化主要是减少堆内存实例对象分配的个数、减少堆内存地址竞争的激烈程度;

GC策略优化主要是减少垃圾回收的时间、减少对服务的中断时间等。

内存分配

在进行内存分配时,我们期望减少在堆上实例对象的分配次数。怎么做呢?

对象实例分配过程

JVM参数优化 java linux jvm如何优化_JVM优化

 

Eden区是连续的内存空间,因此在其上分配内存极快。当Eden区满的时候,会把还活着的对象往一个幸存区放,然后执行一次Minor GC(暂停其他所有线程工作),Eden区和一个幸存区会被清空,这种方式分配内存和清理内存的效率都极高。目前新生代垃圾回收算法,都是要暂停所有线程的执行,只不过将暂停的时间进行缩短

栈上分配 – 减少堆内存使用

栈上分配就是栈帧从栈里被移除后,栈帧里的局部变量就会被销毁。如果考虑把对象实例分配到栈帧里面,就减少了堆内存的占用。但是栈上分配要求考虑逃逸分析和标量替换。

  1. 逃逸分析:实例对象必须是方法的局部变量,该对象不能声明在方法外,也不能作为返回值,因为这样就提供了对外的引用,对象逃逸出了方法的范围,就不是局部变量了。

栈上分配是对局部变量来说的。

JVM参数优化 java linux jvm如何优化_JVM_02

 

  1. 标量替换:通过逃逸分析,确定该对象是局部变量后,就会将该对象成员变量分解,打散到栈帧局部变量表里面。
  2. JVM参数配置:

-server -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations

-XX:+DoEscapeAnalysis – 逃逸分析

-XX:+EliminateAllocations – 标量替换

TLAB-线程本地分配缓存 – 减少堆内存地址竞争

在同一时间,可能会有多个线程在堆上申请空间。因此,每次对象分配都必须要进行同步(虚拟机采用CAS配上失败重试的方式保证更新操作的原子性),而在竞争激烈的场合分配的效率又会进一步下降。JVM使用TLAB来避免多线程冲突,在给对象分配内存时,每个线程使用自己的TLAB,这样可以避免线程同步,提高了对象分配的效率。

TLAB本身占用eEden区空间,在开启TLAB的情况下,虚拟机会为每个Java线程分配一块TLAB空间。参数-XX:+UseTLAB开启TLAB,默认是开启的。TLAB空间的内存非常小,缺省情况下仅占有整个Eden空间的1%,当然可以通过选项-XX:TLABWasteTargetPercent设置TLAB空间所占用Eden空间的百分比大小。

JVM参数优化 java linux jvm如何优化_JVM参数优化 java linux_03

 

GC策略

-XX:对于系统级别的JVM配置,配置日志信息等

非-XX:对应用层面上的配置

+启用这个参数;-禁用这个参数

JVM定义了几种垃圾回收算法,了解这几种算法,根据实际情况进行应用配置即可。

JVM参数优化 java linux jvm如何优化_JVM_04