如何consumer的jstack日志

如何consumer的jstack日志,第1张

consumer jstack日志可以使用jstack命令来查看当前JVM中的线程堆栈信息首基,这样可以查看到正在运行的线程,以及哪些线程可能存在问李缺题。可以使用如下命令来生成jstack日志:jstack -l <java_process_id>>jstack.log,其中 <java_process_id>为JVM进程的进程id。可以使用查看jstack.log文件中的内容,来分析哪芹辩当前JVM中线程的堆栈信息。

可以看到堆内存为2G,新生代为768M老年代为1280M,新生代采用ParNew收集器

-XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS

线程栈为512k(默认1024k调小可以增加创建线程数,增加并发量)

同时打印 GC 详细信息和打印 GC 发生时间,当发生OOM时,Dump文件到指定路径

栈空间参数设置

-Xss: 设置线程的最大银山碰栈空间,栈空间越大,方法的递归深度越大

方法区参数设置(方法区大小的参数设置跟jdk版本相关)

jdk1.6,jdk1.7设置方法区永久代的大小

-XX:PermSize=5M

-XX:MaxPermSize=5M 最大永久代的大小默认是64M

jdk1.8及以上,永久代被移除,取而代之的是元数据区,元数据区是一块堆外的直接内存

如果不指定大小,那么会耗尽所有可用的系统内存

-XX:MaxMetaspaceSize=60M 设置最大元数据的大小

堆设置

-Xms:初始堆大小

-Xmx:最大堆大小

-Xmn:设置新生代大小,设置较大的新生代大小会减小老年代大小,新生代的大小一般为堆空间的1/3

-XX:NewSize=n: 设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值(老年代/新生代)。如:为3,表示年轻代与年老代比值为1:3

年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。

-Xmn,-XX:NewSize/-XX:MaxNewSize,-XX:NewRatio 3组参数都可以影响年轻代的大小,混合使用的情况下,优先级是什么?

1.高优先级:-XX:NewSize/-XX:MaxNewSize

2.中优先级:-Xmn(默认等效 -Xmn=-XX:NewSize=-XX:MaxNewSize=?)

3.低优先级:-XX:NewRatio

推荐使用-Xmn参数,原因是这个参数简洁,相当于一次设定 NewSize/MaxNewSIze而且两者相等,适用于生产环境。

-Xmn 配合 -Xms/-Xmx,即可将堆内存布局完成 -Xmn参数是在JDK 1.4 开始支持

下面两个参数配合使用,当系统发生堆空间不足时,会导出整个堆的信息,且导出到指定的文件中去,后面用MAT工具分析

-XX:HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=d:/a.dump

直接内存配置

-XX:MaxDirectMemorySize

设置直接内存大小,如果不设置,默认值为最大堆空间,即-Xmx指定的大小,当达到指定值时,

会触发垃圾回收,如果回收后也无法释放空间,那么将会抛出OOM

-XX:+UseSerialGC:新生代,老年代都使用串行收集器

-XX:+UseParNewGC:新生代使用ParNew收集器,老年代使用串锋谈行收集器Serial

(jdk9,10已经废除,因为ParNew只能和CMS收集器配合使用,而jdk9,10使用的默认收集器是G1)

-XX:+UseParallelGC:新生代使用ParallelGC,老年代使用串行收集器Serial

-XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行回收器Serial

-XX:+UseParallelOldGC:新生代使用ParallelGC回收唯者器,老年代使用ParallelOldGc回收器

两个重要参数

-XX:MaxGCPasuseMillis:设置最大垃圾回收停顿时间,设置的过小,可能导致垃圾回收频率加大

-XX:GCTimeRatio:设置吞吐量大小,取值范围为0-100,系统回收垃圾的停顿时间花费不超过1/(1+n)%

设置线程数量

-XX:ParallelGCThreads

-XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS

CMS默认启动的并发线程数量为(parallelGCTheads+3)/4

设置并发线程数

-XX:ConcGCThreads=n

-XX:ParallelGCThreads=n

设置老年代空间使用率达到多少时执行CMS垃圾回收

-XX:CMSInitiatingOccupancyFraction 默认值为68

碎片整理参数,如果碎片不整理,可能造成没达到阈值就会触发老年代垃圾回收

-XX:+UseCMSCompactAtFullCollection :在CMS垃圾收集完成之后,进行一次内存碎片整理

-XX:+CMSFullGCsBeforeCompaction=n :在n次CMS回收后进行一次内存碎片整理

使用CMS回收方法去的perm区,默认情况下,还需要触发一次FullGC

-XX:+CMSClassUnloadingEnabled

XX:UseG1GC 开启G1垃圾收集器

两个重要的参数

-XX:MaxGcPasuseMillis :指定目标最大停顿时间,如果停顿的时间过小,一次收集的区域数量也会变小

就会增加FullGC的可能

-XX:parallelGCThreads :设置并行回收的GC线程数量

-XX:InitiatingHeapOccupancyPercent :设置整个堆使用率达到多少时,触发并发标记的执行,默认是45

-XX:+PrintGC 在程序运行期间,只要遇到GC,就会打印GC情况

占用大小->gc后大小 GC消耗时间

jdk9,jdk10默认使用G1收集器,所以打印GC参数不同

-Xlog:gc

-XX:+PrintGCDetails 打印GC详细信息(JDK8,9,10建议使用-Xlog:gc*)

-XX:+PrintGCTimeStamps 打印分析GC发生的时间

-XX:+PrintGCApplicationConcurrentTime 打印应用程序的执行时间

-XX:+PrintGCApplicationStoppedTime 打印GC产生停顿的时间

-Xloggc:/usr/local/log/gc.log 让gc日志打印在log文件夹下的gc文件中,因为默认情况下gc日志在控制台输出

栈上分配,逃逸分析(方法内的变量被外部引用)

允许对象直接在栈上进行分配,随线程停止而销毁,这样做可以加快分配速度,减少GC次数

栈空间较小,所以不适合大对象的栈上分配

-XX:+DoEscapeAnalysis 启用逃逸分析

-XX:+EliminateAllocations 开启标量替换(默认打开),允许对象打散分配在栈上

比如对象拥有id和name两个字段,那么这两个字段将会被视为两个独立的变量进行分配。

对象晋升

-MaxTenuringThreshold=n ,当对象经历了多少次GC次数后进入老年代

注意:大对象直接晋升到老年代

-PretenureSizeThreshold=n 这里的单位是字节,新生对象大于这个值的时候,会直接分配到老年代

1、对存活对象标注时间过长:比如重载了Object类的Finalize方法,导致标注Final Reference耗时过长;或者String.intern方法使用不当,导致YGC扫描StringTable时间过长。

2、长周期对象积累过多:比如本地缓存使用不当,积累了太多存活对象;或者锁竞争严重导致线程阻塞,局部变量的生命周期变长

当Eden区空间不足时,就会触发YGC。结合新生代对象的内存分配看下详细过程:

1、新对象会先尝试在栈上分配,如果不行则尝试在TLAB分配,否则再看是否满足大对象条件要在老年代分配,最后才考虑在Eden区申请空间。

2、如果Eden区没有合适的空间,则触发YGC。

3、YGC时,对Eden区和From Survivor区的存活对象进行处理,如果满足动态年龄判断的条件或者To Survivor区空间不够则直接进入老年代,如果老年代空间也不够了,则会发生promotion failed,触发老年代的回收。否则将存活对象复制到To Survivor区。

4、此时Eden区和From Survivor区的剩余对象均为垃圾对象,可直接抹掉回收。

此外,老年代如果采用的是CMS回收器,为了减少CMS Remark阶段的耗时,也有可能会触发一次YGC,这里不作展开。

大多数情况下,对象直接在年轻代中的Eden区进行分配,如果Eden区域没有足够的空间,那么就会触发YGC(Minor GC),YGC处理的区域只有新生代。因为大部分对象在短时间内都是可收回掉的,因此YGC后只有极少数的对象能存活下来,而被移动到S0区(采用的是复制算法)。当触发下一次YGC时,会将Eden区和S0区的存活对象移动到S1区,同时清空Eden区和S0区。当再次触发YGC时,这时候处理的区域就变成了Eden区和S1区(即S0和S1进行角色交换)。每经过一次YGC,存活对象的年龄就会加1。

下面4种情况,对象会进入到老年代中:

当晋升到老年代的对象大于了老年代的剩余空间时,就会触发FGC(Major GC),FGC处理的区域同时包括新生代和老年代。除此之外,还有以下4种情况也会触发FGC:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12301597.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存