Back

JVM笔记之调优及参数

调优

调优时机

  1. 内存(⽼年代)持续上涨达到设置的最大内存值;
  2. Full GC 次数频繁;
  3. GC 停顿时间过长(超过1秒);
  4. 应用出现OutOfMemory 等内存异常;
  5. 应⽤中使用本地缓存占用大量内存空间;
  6. 系统吞吐量量与响应性能不高或下降。

调优原则

  1. 多数的Java应用不需要在服务器上进行JVM优化,JVM优化是到最后不得已才采用的⼿段;
  2. 多数导致GC问题的Java应用,往往是代码问题,分析GC情况优化代码;
  3. 在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);
  4. 减少创建对象的数量;
  5. 减少使用全局变量和大对象

调优目标

GC低停顿、低频率; 低内存占用;⾼吞吐量

调优步骤

  1. 分析GC日志及dump⽂文件,判断是否需要优化,确定瓶颈问题点;
  2. 确定jvm调优量化目标;
  3. 确定jvm调优参数(根据历史jvm参数来调整);
  4. 调优一台服务器,对比观察调优前后的差异;
  5. 不断的分析和调整,直到找到合适的jvm参数配置;
  6. 找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。

参数

堆参数设置

  • -Xms 设置Java程序启动时初始化JVM堆内存大小。

  • -Xmx 设置Java程序能获得最大JVM堆内存大小。

  • -XX:+PrintGC 使用这个参数,虚拟机启动后,只要遇到GC就会打印日志。

  • -XX:+PrintGCDetails 可以查看详细信息,包括各个区的情况

  • -XX:+PrintHeapAtGC 打印 GC 前后的详细堆栈信息

  • -XX:+PrintFlagsInitial打印JVM初始化参数。

  • -XX:+PrintFlagsFinal 标记人为修改过的参数。

  • -XX:+PrintCommandLineFlags 查看默认垃圾回收器。

新生代参数设置

  • -XX:NewSize=5m 设置新生代最小空间大小

  • -XX:MaxNewSize=10m 设置新生代最大空间大小

  • -Xmn2g 设置新生代大小为2G,设置一个比较大的新生代会减少老年代的大小,这个参数对系统性能以及GC行为有很大的影响,新生代大小一般会设置整个堆空间的1/3

  • -XX:SurvivorRatio=8(默认)用来设置新生代中eden空间和from/to空间的比例。-XX:SurvivorRatio=eden/from=eden/to。

基本策略:尽可能将对象预留在新生代,减少老年代的GC次数。

  • -XX:NewRatio=2(默认)设置新生代和老年代的比例 。-XX:NewRatio=老年代/新生代。

对象进入老年代参数设置

-XX:MaxTenuringThreshold=15

新生代每次GC之后如果对象没有被回收,则年龄加1,默认情况下为15

堆溢出参数配置

-XX:+HeapDumpOnOutOfMemoryError

使用该参数可以在内存溢出时导出整个堆信息

-XX:HeapDumpPath=D:/OOM.dump

可以设置导出堆的存放路径。

堆栈相关参数配置

 -Xss1m(默认)   来指定线程的最大栈空间

方法区相关参数配置

JDK1.2 ~ JDK6,使用永久代来实现方法区

-XX:PermSize=64M

设置永久代最小空间大小。

-XX:MaxPermSize=64M(默认)

如果系统运行时生产大量的类,就需要设置一个相对合适的方法区,以免出现永久区内存溢出的问题。

Java8,元空间取代永久代,存储位置不同,永久代物理是堆的一部分,和新生代,老年代地址是连续的

而元数据放到本地化的堆内存(native heap)中,这一块区域就叫Metaspace

-XX:MetaspaceSize=128m(默认)

初始化大小。

 -XX:MaxMetaspaceSize=128m 

JVM默认在运行时根据需要动态地设置MaxMetaspaceSize的大小。

直接内存(堆外内存)参数配置

-XX:MaxDirectMemorySize=64m

该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory()。 直接内存使用达到上限时,就会触发垃圾回收(Full GC),如果不能有效的释放空间,就会引起系统的OOM。

TLAB参数配置

Thread Local Allocation Buffer即线程本地分配缓存:

一个线程专用的内存分配区域,是为了加速对象分配对象而生的。每一个线程都会产生一个TLAB,该线程独享的工作区域,Java虚拟机使用这种TLAB区避免多线程冲突问题,提高了对象分配的效率。

-XX:+UseTLAB(默认开启)

使用TLAB

-XX:TLABSize=64k(默认) 

设置TLAB初始化大小

-XX:TLABRefillWasteFraction=64

设置维护进入TLAB空间的单个对象大小,它是一个比例值,默认为64,即如果对象大于整个空间的1/64,则在堆创建对象。

 -XX:+ResizeTLAB 

自调整TLABRefillWasteFraction阈值。

-XX:+PrintTLAB 

查看TLAB信息

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus