您当前的位置:生活大视野资讯正文

JVM图文系列一文学会JVM功能优化

放大字体  缩小字体 2019-11-08 19:26:37  阅读:8319 作者:责任编辑NO。杜一帆0322

9 实战功能优化

9.1 从头认知JVM

之前咱们画过一张图,是从Class文件到类装载器,再到运转时数据区的进程,现在咱们把这张图无妨丰厚完善一下,展现了JVM的大体物理结构图。

履行引擎:用于履行JVM字节码指令

主要由两种完结办法:

(1)将输入的字节码指令在加载时或履行时翻译成别的一种虚拟机指令;

(2)将输入的字节码指令在加载时或履行时翻译成宿主主机本地CPU的指令集。这两种办法对应着字节码的解说履行和即时编译。

9.2 堆内存溢出

9.2.1 代码

记住设置参数比方-Xmx20M -Xms20M

9.2.2 运转成果

拜访->http://localhost:8080/heap

Exception in thread "http-nio-8080-exec-2" java.lang.OutOfMemoryError: GC overhead limit exceeded

9.2.3 回忆jps和jinfo

9.2.4 回忆jmap手动导出和参数主动导出

jmap手动导出:jmap -dump:format=b,file=heap.hprof PID

参数主动导出:

-XX:+HeapDumponOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof

9.3 办法区内存溢出

比方向办法区中添加Class的信息

9.3.1 asm依靠和Class代码

9.3.2 代码

设置metaspace的巨细,比方-XX:metaspaceSize=50M -XX:MaxmetaspaceSize=50M

9.3.3 运转成果

拜访->http://localhost:8080/nonheap

9.4 虚拟机栈

9.4.1 代码演示StackOverFlow

9.4.2 运转成果

9.4.3 阐明

Stack Space用来做办法的递归调用时压入Stack frame(栈帧)。所以当递归调用太深的时分,就有或许耗尽Stack Space,爆出StackOverflow的过错。

-Xss128k:设置每个线程的仓库巨细。JDK 5今后每个线程仓库巨细为1M,曾经每个线程仓库巨细为256K。根据运用的线程所需内存巨细做调整。在相同物理内存下,减小这个值能生成更多的线程。可是操作体系对一个进程内的线程数仍是有约束的,不能无限生成,经验值在3000~5000左右。

线程栈的巨细是个双刃剑,假如设置过小,或许会呈现栈溢出,特别是在该线程内有递归、大的循环时呈现溢出的或许性更大,假如该值设置过大,就有影响到创立栈的数量,假如是多线程的运用,就会呈现内存溢出的过错。

9.5 线程死锁

9.5.1 代码

9.4.2 运转成果

9.4.3 jstack剖析

把打印信息拉到终究能够发现

9.4.4 jvisualvm

将线程信息dump出来

9.6 废物搜集

内存被运用了之后,不免会有不行用或许到达设定值的时分,就需要对内存空间进行废物收回。

9.6.1 废物搜集发作的机遇

GC是由JVM主动完结的,根据JVM体系环境而定,所以机遇是不确定的。

当然,咱们咱们能够手动进行废物收回,比方调用System.gc()办法告诉JVM进行一次废物收回,可是详细什么时刻运转也无法控制。也就是说System.gc()仅仅告诉要收回,何时收回由JVM决议。

可是不主张手动调用该办法,由于耗费的资源比较大。

一般以下几种状况会发作废物收回

(1)当Eden区或许S区不行用了

(2)老时代空间不行用了

(3)办法区空间不行用了

(4)System.gc()

尽管废物收回的机遇是不确定的,可是能够结合之前一个方针的一辈子事例,文字图解再次整理一下堆内存收回的流程。

一个方针的一辈子

我是一个一般的Java方针,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,咱们在Eden区中玩了挺长期。

有一天Eden区中的人实在是太多了,我就被逼去了Survivor区的“From”区,自从去了Survivor区,我就开端漂了,有时分在Survivor的“From”区,有时分在Survivor的“To”区,居无定所。直到我18岁的时分,爸爸说我成人了,该去社会上闯闯了。

所以我就去了年迈代那儿,年迈代里,人许多,而且年纪都挺大的,我在这儿也认识了许多人。在年迈代里,我生活了20年(每次GC加一岁),然后被收回。

9.6.2 试验环境预备

我的本地机器运用的是jdk1.8和tomcat8.5,咱们也能够正常的运用linux上的tomcat,然后把gc日志下载下来即可。

9.6.3 GC日志文件

回忆提高一下废物搜集器图

要想剖析日志的信息,得先拿到GC日志文件才行,所以得先装备一下,之前也看过这些参数。

比方翻开windows中的catalina.bat,在榜首行加上

set JAVA_OPTS=%JAVA_OPTS% -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log

这样运用startup.bat发动tomcat的时分就能够在当时目录下拿到gc.log文件

能够正常的看到默许运用的是ParallelGC

9.6.3.1 Parallel GC日志

【吞吐量优先】

2019-06-10T23:21:53.305+0800: 1.303: [GC (Allocation Failure) [PSYoungGen: 65536K[Young区收回前]->10748K[Young区收回后](76288K[Young区总巨细])] 65536K[整个堆收回前]->15039K[整个堆收回后](251392K[整个堆总巨细]), 0.0113277 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

`留意`假如收回的差值中心有收支,阐明这部分空间是Old区释放出来的

9.6.3.2 CMS日志

【中止时刻优先】

参数设置

重启tomcat获取gc日志,这儿的日志格局和上面差不多,不作剖析。

9.6.3.3 G1日志

G1日志格局参阅链接:

https://blogs.oracle.com/poonam/understanding-g1-gc-logs

【中止时刻优先】

why?

https://blogs.oracle.com/poonam/increased-heap-usage-with-g1-gc

参数设置

9.6.4 GC日志文件剖析东西

9.6.4.1 gceasy

能够比较不同的废物搜集器的吞吐量和中止时刻

9.6.4.2 GCViewer

9.6.5 G1调优

是否选用G1废物搜集器的判别根据

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases

(1)50%以上的堆被存活方针占用

(2)方针分配和提升的速度改变非常大

(3)废物收回时刻比较长

(1)运用G1GC废物搜集器: -XX:+UseG1GC

修正装备参数,获取到gc日志,运用GCViewer剖析吞吐量和呼应时刻

(2)调整内存巨细再获取gc日志剖析

比方设置堆内存的巨细,获取到gc日志,运用GCViewer剖析吞吐量和呼应时刻

(3)调整最大中止时刻

比方设置最大中止时刻,获取到gc日志,运用GCViewer剖析吞吐量和呼应时刻

(4)发动并发GC时堆内存占用百分比

-XX:InitiatingHeapOccupancyPercent=45 G1用它来触发并发GC周期,根据整个堆的运用率,而不仅仅某一代内存的运用份额。值为 0 则表明“一向履行GC循环)'. 默许值为 45 (例如, 悉数的 45% 或许运用了45%).

比方设置该百分比参数,获取到gc日志,运用GCViewer剖析吞吐量和呼应时刻

9.6.6 G1调优的最佳实践

官网主张:

(https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations)

(1)不要手动设置新生代和老时代的巨细,只需设置整个堆的巨细

G1搜集器在运转进程中,会自己调整新生代和老时代的巨细

其实是经过adapt代的巨细来调整方针提升的速度和年纪,从而到达为搜集器设置的暂停时刻方针

假如手动设置了巨细就从另一方面代表着抛弃了G1的主动调优

(2)不断调优暂停时刻方针

正常的状况下这个值设置到100ms或许200ms都是能够的(不同状况下会不一样),但假如设置成50ms就不太合理。暂停时刻设置的太短,就会导致呈现G1跟不上废物发生的速度。终究退化成Full GC。所以对这个参数的调优是一个继续的进程,逐渐调整到最佳状况。暂停时刻仅仅一个方针,并不能总是得到满意。

(3)运用-XX:ConcGCThreads=n来添加符号线程的数量

IHOP假如阀值设置过高,或许会遇到搬运失利的危险,比方方针进行搬运时空间缺乏。假如阀值设置过低,就会使符号周期运转过于频频,而且有或许混合搜集期收回不到空间。

> IHOP值假如设置合理,可是在并发周期时刻过长时,能够测验添加并发线程数,调高ConcGCThreads。

(4)MixedGC调优

-XX:InitiatingHeapOccupancyPercent

-XX:G1MixedGCLiveThresholdPercent

-XX:G1MixedGCCountTarger

-XX:G1OldCSetRegionThresholdPercent

(5)恰当添加堆内存巨细

9.7 一张图总结JVM功能优化

全文完!

欢迎重视“Java架构师学习”

假如觉得不错,请给个「在看」

共享给你的朋友!

THANDKS

- End -

“如果发现本网站发布的资讯影响到您的版权,可以联系本站!同时欢迎来本站投稿!