Java JVM调优五大技能详解

目录
  • 1.什么时候需要JVM调优
  • 2.JVM调优一般调什么
  • 3.JVM调优基本步骤
    • 3.1添加GC日志相关的参数
    • 3.2添加内存溢出与Full gc前快照输出参数
    • 3.3通过日志确定问题
      • 3.3.1堆内存不足
      • 3.3.2频繁Full gc
  • 4.监控工具
    • 4.1使用jstat 统计gc相关信息
    • 4.2使用jmap命令查某时刻的JVM堆信息
  • 5.常用的调优工具有哪些?
  • 总结

1.什么时候需要JVM调优

  • 应用的响应慢、CPU占用高
  • 应用吞吐量小,占用内存空间过大

这些表象一般伴随着频繁的垃圾回收,或者OOM。

2.JVM调优一般调什么

  • 应用占用的内存(堆内存,元空间内存)
  • 新生代老年代的大小,比例。
  • 垃圾回收器的选择。

堆内存参数

| -Xms512m | 初始堆大小

默认值:若未设置,初始值将是老年代和年轻代分配制内存之和
-Xmx1024m

年轻代内存相关参数

| -Xmn512m | 新生代的初始值及最大值。

默认值:堆内存的1/4(已经分配的堆内存的1/4)。
-XX:NewSize=512m
-XX:MaxNewSize=512m
-XX:NewRatio=8

比如-XX:NewRatio=8

表示:老年代内存:年轻代内存=8:1 |

| -XX:SurvivorRatio=8 | 新生代和存活区的比例

-XX:SurvivorRatio=8

表示存活区:新生代=1:8 =》新生代占年轻代的8/10,每个存活区各占年轻代的1/10 |

元空间参数

| -XX:MetaspaceSize | 初始元空间大小

达到该值就会触发垃圾收集进行类型卸载
-XX:MaxMetaspaceSize=256m

3.JVM调优基本步骤

首先在启动程序的时候

3.1添加GC日志相关的参数

-XX:+PrintGC:输出GC日志
-XX:+PrintGCDetails:输出GC的详细日志
-XX:+PrintGCTimeStamps:输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps:输出GC的时间戳(以日期的形式,如2018-08-29T19:22:48.741-0800)
-XX:+PrintHeapAtGC:在进行GC的前后打印出堆的信息
-Xloggc:gc.log:日志文件的输出路径

3.2添加内存溢出与Full gc前快照输出参数

-XX:+HeapDumpOnOutOfMemoryError 发生内存溢出时生成heapdump文件
-XX:+HeapDumpBeforeFullGC 发生Full gc前生成heapdump文件
-XX:HeapDumpPath:指定heapdump输出路径

3.3通过日志确定问题

3.3.1堆内存不足

  • 排查是否是设置的堆内存过小,还是内存溢出情况。
  • 拿到当时的内存快照,用工具分析 jump用Mat工具分析。

3.3.2频繁Full gc

  • 考虑是否是新上线的代码问题,有大对象占用,导致了频繁YGC,进而导致了晋升至年老代的对象增多,老年代达到内存阈值触发 Full gc ;
  • 考虑是否是新生代设置太小 ;

总结:

若是代码问题可通过版本控制工具找到本期变更的代码,优化代码

若非代码问题,可适当增加堆内存大小、新生代老年代的大小与比例 , 适当增大新生代内存大小。

4.监控工具

4.1使用jstat 统计gc相关信息

jstat 是 jdk bin 下自带工具,最多的是用来统计gc相关信息,使用步骤如下。

获取进程号 ps -ef|grep 对应进程

例如我想统计jvm-demo.jar(进程号27164)的gc信息,并且每隔3秒统计一次,可以执行以下命令

jstat -gcutil 27164 3000

主要关注以下几个。

  • s0、s1:表示两个survior区域的使用百分比
  • e:eden区域使用百分比
  • o:老年代使用百分比
  • m:metaspace(元数据空间)使用百分比
  • ygc:新生代gc次数
  • ygct:新生代gc累计总时间
  • fgc:full gc次数
  • fgct:full gc累计总时间
  • gct:gc累计总时间

若要进一步查看上一次GC信息

jstat -gccause 27146 3000

  • LGCC:上一次gc的原因,Allocation Failure是新生代满了,进行gc
  • gcc:当前gc的原因,如果当前没有gc就no gc

4.2使用jmap命令查某时刻的JVM堆信息

使用步骤

  • 获取进行 pid ps -ef|grep 对应进程
  • 例如我想统计jvm-demo.jar(进程号27164)的信息,并且每隔3秒统计一次,可以执行以下命令
jmap -heap 2865

输出内容示例:

Attaching to process ID 27146, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
using thread-local object allocation.
Mark Sweep Compact GC
#堆相关的配置信息
Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 104857600 (100.0MB)
   NewSize                  = 10485760 (10.0MB)
   MaxNewSize               = 34930688 (33.3125MB)
   OldSize                  = 20971520 (20.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)
#堆占用相关的配置信息
Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 12517376 (11.9375MB)
   used     = 10708296 (10.212226867675781MB)
   free     = 1809080 (1.7252731323242188MB)
   85.54745020042539% used
Eden Space:
   capacity = 11141120 (10.625MB)
   used     = 10708272 (10.212203979492188MB)
   free     = 432848 (0.4127960205078125MB)
   96.11486098345588% used
From Space:
   capacity = 1376256 (1.3125MB)
   used     = 24 (2.288818359375E-5MB)
   free     = 1376232 (1.3124771118164062MB)
   0.0017438616071428572% used
To Space:
   capacity = 1376256 (1.3125MB)
   used     = 0 (0.0MB)
   free     = 1376256 (1.3125MB)
   0.0% used
tenured generation:
   capacity = 27684864 (26.40234375MB)
   used     = 27096504 (25.84123992919922MB)
   free     = 588360 (0.5611038208007812MB)
   97.87479541167332% used
15431 interned Strings occupying 2044328 bytes.

5.常用的调优工具有哪些?

JDK内置的命令行:jps(查看jvm进程信息)、jstat(监视jvm运行状态的,比如gc情况、jvm内存情况、类加载情况等)、jinfo(查看jvm参数的,也可动态调整)、jmap(生成dump文件的,在dump的时候会影响线上服务)、jhat(分析dump的,但是一般都将dump导出放到mat上分析)、jstack(查看线程的)。

JDK内置的可视化界面:JConsoleVisualVM,这两个在QA环境压测的时候很有用。

阿里巴巴开源的arthas:神器,线上调优很方便,安装和显示效果都很友好

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • java虚拟机之JVM调优详解

    JVM常用命令行参数 1. 查看参数列表 虚拟机参数分为基本和扩展两类,在命令行中输入 JAVA_HOME\bin\java就可得到基本参数列表. 在命令行输入 JAVA_HOME\bin\java –X就可得到扩展参数列表. 2. 基本参数说明: -client,-server: 两种Java虚拟机启动方式,client模式启动比较快,但是性能和内存管理相对较差,server模式启动比较慢,但是运行性能比较高,windos上采用的是client模式,Linux采用server模式 -class

  • 优化Java虚拟机总结(jvm调优)

    堆设置 -Xmx3550m:设置JVM最大堆内存为3550M. -Xms3550m:设置JVM初始堆内存为3550M.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存. -Xss128k:设置每个线程的栈大小.JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K.应当根据应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右. -Xmn2g:设置堆

  • eclipse修改jvm参数调优方法(2种)

    本文介绍了eclipse修改jvm参数调优方法(2种),分享给大家,具体如下: 一般在不对eclipse进行相关设置的时候,使用eclipse总是会觉得启动好慢,用起来好卡,其实只要对eclipse的相关参数进行一些配置,就会有很大的改善. 有两种方法: 1.打开eclipse配置文件eclipse.ini,更改把-Xmx(其数值代表jvm可以使用的最大内存数) 2.  运行java程序时,选择run->run configuration->arguments,输入-Xms100M -Xmx8

  • JVM性能调优实战:让你的IntelliJ Idea纵享丝滑

    本文已被Github仓库收录 https://github.com/silently9527/JavaCore 前言 在前面整理了一篇关于JVM故障诊断和处理工具,考虑到大部分的Java程序员都使用的是IntelliJ Idea,本篇就使用工具来实战演练对IntelliJ Idea运行速度调优 调优前的运行状态 原始配置内容 要查询idea原始配置文件的路径可以在VisualVM中的概述中查看 原始配置内容: -XX:ReservedCodeCacheSize=240m -XX:+UseComp

  • 详解JVM中的GC调优

    那些GC的默认值 其实GC或者说JVM的参数非常非常的多,有控制内存使用的: 有控制JIT的: 有控制分代比例的,也有控制GC并发的: 当然,大部分的参数其实并不需要我们自行去调整,JVM会很好的动态帮我们设置这些变量的值. 如果我们不去设置这些值,那么对GC性能比较有影响的参数和他们的默认值有哪些呢? GC的选择 我们知道JVM中的GC有很多种,不同的GC选择对java程序的性能影响还是比较大的. 在JDK9之后,G1已经是默认的垃圾回收器了. 我们看一下G1的调优参数. G1是基于分代技术的

  • Java JVM调优五大技能详解

    目录 1.什么时候需要JVM调优 2.JVM调优一般调什么 3.JVM调优基本步骤 3.1添加GC日志相关的参数 3.2添加内存溢出与Full gc前快照输出参数 3.3通过日志确定问题 3.3.1堆内存不足 3.3.2频繁Full gc 4.监控工具 4.1使用jstat 统计gc相关信息 4.2使用jmap命令查某时刻的JVM堆信息 5.常用的调优工具有哪些? 总结 1.什么时候需要JVM调优 应用的响应慢.CPU占用高 应用吞吐量小,占用内存空间过大 这些表象一般伴随着频繁的垃圾回收,或者

  • jvm垃圾回收之GC调优工具分析详解

    进行GC性能调优时, 需要明确了解, 当前的GC行为对系统和用户有多大的影响.有多种监控GC的工具和方法, 本章将逐一介绍常用的工具. JVM 在程序执行的过程中, 提供了GC行为的原生数据.那么, 我们就可以利用这些原生数据来生成各种报告.原生数据(raw data) 包括: 各个内存池的当前使用情况, 各个内存池的总容量, 每次GC暂停的持续时间, GC暂停在各个阶段的持续时间. 可以通过这些数据算出各种指标, 例如: 程序的内存分配率, 提升率等等.本章主要介绍如何获取原生数据. 后续的章

  • jmeter在linux系统下运行及本地内存调优的方法详解

    1.在linux系统下安装跨系统传输文件工具 root用户下 根目录输入 yum -y install lrzsz 2.把apache-jmeter-4.0zip包 用rz命令上传到linux系统的根目录下 解压 3.配置jmeter环境变量 vim /etc/profile 添加 export PATH=/apache-jmeter-4.0/bin/:$PATH 注意路径 4.使用 rz命令上传jdk1.8 linux 64位版本 解压到 usr/local 目录下 下载jdk安装包 下载地址

  • Mysql调优Explain工具详解及实战演练(推荐)

    Mysql调优Explain工具详解以及实战演练 Explain工具介绍Explain分析示例explain 两个变种explain中的列 索引最佳实战索引使用总结: Mysql安装文档参考 Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是 执行这条SQL 注意:如果 from 中包含子查询,仍会执行该子

  • Java jvm中Code Cache案例详解

    Code Cache JVM生成的native code存放的内存空间称之为Code Cache:JIT编译.JNI等都会编译代码到native code,其中JIT生成的native code占用了Code Cache的绝大部分空间 相关参数 Codecache Size Options -XX:InitialCodeCacheSize 用于设置初始CodeCache大小 -XX:ReservedCodeCacheSize 用于设置Reserved code cache的最大大小,通常默认是2

  • JAVA JVM运行时数据区详解

    目录 一.前言 二.运行时数据区整体概架构 三.程序计数器 四.虚拟机栈 1.栈的特点 2.栈帧的内部结构 3.局部变量表 4.操作数栈 5.动态链接 6.方法返回地址 五.本地方法栈 六.堆 1.设置堆大小的参数 2.对象分配过程 3.堆中的GC 4.内存分配策略 5.什么是TLAB 6.堆是分配对象存储的唯一选择吗? 七.方法区 1.方法区概述 2.设置方法区内存大小 3.如何解决OOM问题? 4.方法区存储什么 5.方法区的演进细节 6.方法区的GC 总结 一.前言 这是JVM系列文章的第

  • java自旋锁和JVM对锁的优化详解

    目录 背景 好处 AtomicLong的实现 getAndIncrement方法 实验 缺点 适用场景 JVM对锁做了哪些优化? 自适应的自旋锁 锁消除 锁粗化 偏向锁/ 轻量级锁/ 重量级锁 锁升级 背景 先上图 由此可见,非自旋锁如果拿不到锁会把线程阻塞,直到被唤醒: 自旋锁拿不到锁会一直尝试 为什么要这样? 好处 阻塞和唤醒线程都是需要高昂的开销的,如果同步代码块中的内容不复杂,那么可能转换线程带来的开销比实际业务代码执行的开销还要大. 在很多场景下,可能我们的同步代码块的内容并不多,所以

  • Java 线程池全面总结与详解

    目录 原理 阻塞队列 有界阻塞队列 无界阻塞队列 同步移交队列 实现类分析 使用Executors创建线程池 线程池关闭 线程池是很常用的并发框架,几乎所有需要异步和并发处理任务的程序都可用到线程池. 使用线程池的好处如下: 降低资源消耗:可重复利用已创建的线程池,降低创建和销毁带来的消耗: 提高响应速度:任务到达时,可立即执行,无需等待线程创建: 提高线程的可管理性:线程池可对线程统一分配.调优和监控. 原理 线程池的原理非常简单,这里用处理流程来概括: 线程池判断核心池里的线程是否都在执行任

随机推荐