暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

JVM参数知一二

原创 飞鸟-柯 2022-12-21
224

在日常的Java开发中,常见以下问题:

内存泄露某个进程突然cpu飙升线程死锁响应变慢如果遇到了以上这种问题,如何JAVA内存管理、垃圾回收、内存调优,来解决运行日志、异常堆栈、GC日志、线程快照、堆快照等问题?

01java自带分析工具

通过java自带分析工具,如jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令,分析和监控工具可以加快我们的分析数据、定位解决问题的速度。

jstack:java堆栈跟踪工具

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

命令格式:

jstack [ option ] pidjstack [ option ] executable corejstack [ option ] [server-id@]remote-hostname-or-IP参数:

-F :当’jstack [-l] pid’没有相应的pid时,强制打印栈信息 。-l:长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表。-m:打印java和native c/c++框架的所有栈信息。-h | -help:打印帮助信息 pid 需要被打印配置信息的java进程id,可以用jps查询。1、过滤指定线程,打印堆栈信息

指令: jstack pid |grep 'threadPid' -C5 --color jstack 13525 |grep '0x3be4' -C5 --color // 打印进程堆栈 并通过线程id,过滤得到线程堆栈信息。

2、查看java进程的线程快照信息

指令:jstack -l pid

从输出信息可以看到,有一个线程死锁发生,并且指出了那行代码出现的。如此可以快速排查问题。

jmap-->java 内存映射工具

jmap命令用于生产堆转存快照。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。

jmap [ option ] pidjmap [ option ] executable corejmap [ option ] [server-id@]remote-hostname-or-IP参数选项:

-dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件。live子选项是可选的,假如指定live选项,那么只输出活的对象到文件。-finalizerinfo 打印正等候回收的对象的信息。-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。-histo[:live] 打印每个class的实例数目、内存占用、类全名信息。VM的内部类名字开头会加上前缀”*”。如果live子参数加上后,只统计活的对象数量。-permstat 打印classload和jvm heap长久层的信息,包含每个classloader的名字、活泼性、地址、父classloader和加载的class数量。另外,内部String的数量和占用内存数也会打印出来。-F 强迫。在pid没有相应的时候,使用-dump或者-histo参数。在这个模式下,live子参数无效。-h | -help 打印辅助信息。-J 传递参数给jmap启动的jvm。例如:

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况:

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图。

jstat: jvm统计信息监控工具

jstat 是用于虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、jit编译等运行数据,它是线上定位jvm性能的首选工具。

命令格式:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

generalOption :单个的常用的命令行选项,如-help, -options, 或 -version。outputOptions :一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。常用选项:

class:用于查看类加载情况的统计,jstat -class pid:显示加载class的数量,及所占空间等信息。compiler:查看HotSpot中,即时编译器编译情况的统计,jstat -compiler pid:显示VM实时编译的数量等信息。gc 查看JVM中堆的垃圾收集情况的统计, jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。gccapacity:查看新生代、老生代及持久代的存储容量情况,jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小gccause :查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。 jstat -gccause:显示gc原因找到java安装目录cd .../bin/,再执行./jstack ...

看gc 情况执行:jstat-gcutil 27777

02堆大小设置

JVM初始分配的内存,由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆,直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆,直到-Xms的最小限制。因此服务器一般设置-Xms与-Xmx相等,以避免在每次GC 后调整堆的大小。

堆常用设置

-Xms:初始堆大小-Xmx:最大堆大小-XX:NewSize=n:设置年轻代大小-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5-XX:MaxPermSize=n:设置持久代大小收集器设置

-XX:+UseSerialGC:设置串行收集器-XX:+UseParallelGC:设置并行收集器-XX:+UseParalledlOldGC:设置并行年老代收集器-XX:+UseConcMarkSweepGC:设置并发收集器垃圾回收统计信息

-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:filename并行收集器设置

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)并发收集器设置

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

03堆大小典型设置

JVM 中最大堆大小有三方面限制:

相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。在32位系统下,一般限制在1.5G~2G,64为操作系统对内存无特定限制。

机器配置:128G内存 32核CPU典型设置: java -Xmx72g -Xms72 -Xmn4g -Xss256m

-Xmx72g:设置JVM最大可用内存为72g。-Xms72g:设置JVM最小内存为72g。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。-Xmn4g:设置年轻代大小为4G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。(注:这里默认的使用的JVM是Sun的Hotspot,而其中使用GC算法就是分代算法。若要了解详情,可以参考一些关于JVM的书: 《深入理解Java虚拟机》第二版 )-Xss256m:设置每个线程的堆栈大小。JDK5.0以后,每个线程堆栈大小为1M,以前每个线程堆栈大小为128k。更新应用的线程,所需内存大小进行调整。在相同物理内存下,减小这个值,能生成更多的线程。但是操作系统,对一个进程内的线程数,还是有限制的,不能无限生成,经验值在3000~5000左右。

java -Xmx72g -Xms72g -Xss256m -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=0

解释:

-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。-XX:MaxPermSize=256m:设置持久代大小为256m。-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。 对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概率。

最后修改时间:2022-12-21 17:44:43
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论