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 -