Java Performance Definitive Guide Reading Notes

JIT即时编译器

JIT(Just In Time) 即时编译器

  • 对于所有的应用都应该使用server编译器和分层编译
  • 只要保证代码缓存足够大,编译器就能够提供尽善尽美的性能

代码缓存

通常只需要设置代码缓存的最大值:-XX:ReservedCodeCacheSize,代码缓存的初始大小(-XX:InitialCodeCacheSize)JVM会自动帮你设置,缓存的大小会在后台自动调整。

java -jar -XX:ReservedCodeCacheSize=240m yeti-apiapp-1.0.jar

编译阈值

client编译器默认值1500,server编译器默认值10000,更改CompileThreshold会使编译器提前或延后编译,所以一定要根据需求进行设置。

java -jar -XX:CompileThreshold=10000 yeti-apiapp-1.0.jar

检测编译过程

开启PrintCompilation,每次编译一个方法或循环时,JVM就会打印一行被编译的内容信息

java -jar -XX:+PrintCompilation yeti-apiapp-1.0.jar

image-20210809162415705

jstat -compiler 5040
jstat -printcompilation 5040 1000

编译线程

java -jar -XX:CICompilerCount=4 yeti-apiapp-1.0.jar

垃圾收集入门

image-20210809170019076

**Minor GC的原理:**新生代填满时,垃圾收集器会暂停所有的应用线程,回收Young Generation空间,不再使用的对象会被回收,仍在使用的对象会移到Survivor或者Old Generaton中,对于这种操作我们称为Minor GC。

Serial GC

Clinet型虚拟机,Serial使用单线程清理堆的内容,进行Minor GC和Full GC时,所用应用线程都会被暂停。

开启:-XX:+UseSerialGC,默认情况下时开启的。

关闭:关闭可以通过指定另外一种垃圾收集器实现。

Throughput GC

Server型虚拟机的默认收集器,Throughput使用多线程清理堆内容,进行Minor GC和Full GC时,所用应用线程都会被暂停。

在进行Full GC时会对老年代空间进行压缩整理。

开启:默认开启,-XX:+UseParallelGC,-XX:+UseParallelOldGC

CMS GC

Minor GC阶段,暂停应用线程,使用多线程进行回收,使用全新的算法(-XX:+UseParNewGC)。

Old Generation的回收,使用多个线程定期的对Old Generation空间进行扫描,及时回收不再使用的空间。

应用程序线程停顿的总时长比Throughput短得多。

缺点:

  • 使用更多的CPU。
  • 不进行压缩整理工作,导致堆碎片化,过度碎片化会退化到Serial收集器行为。

G1 GC

适合于超大堆,降低stop-the-world。

G1将堆划分若干个区域(Region)。

G1收集器实现了堆的部分压缩整理,相比CMS不容易发生Full GC。

开启:

java -jar -Xms6144m -Xmx6144m -XX:+UseG1GC yeti-apiapp-1.0.jar
java -jar -XX:+UseG1GC yeti-apiapp-1.0.jar

调整堆大小

  • JVM会根据运行的机器,尝试估算最小、最大堆。
  • 尽量不要调整堆的大小,除非需要比默认值更大的堆。
  • 如果确定应用程序需要多大的堆,可以将堆的初始值和最大值设置成相同大小(-Xms1024m -Xmx1024m),此方法不需要估算堆是否需要调整大小,因此可以稍微提高GC运行效率。
java -jar -Xms1024m -Xmx1024m yeti-apiapp-1.0.jar

调整代空间大小

所有调整代空间的标志,都是调整Young Generation空间,剩下的便是Old Generation的空间。

设置新生代空间占用比例,默认值2,经过计算新生代空间大小是初始堆大小的33%
-XX:NewRatio=N
Initial Young Gen Size = Initial Heap Size / (1 + NewRatio)
设置新生代空间初始大小-XX:NewSize=N
设置新生代空间最大大小-XX:MaxNewSize=N
设置初始大小和最大大小快捷方式-Xmn100m

如果堆的大小是确定的,可以指定代空间的最大值和最小值,否则最好使用-XX:NewRatio,按照比率调整。

调整元空间大小

JVM载入类的时候,类的元数据就会保存到元空间(Metaspace)。

-XX:MetaspaceSize=N-XX:MaxMetaspaceSize=N

调整并发线程数

-XX:ParallelGCTheads=N

开启GC日志功能

显式的输出

java -jar -XX:+PrintGCDetails yeti-apiapp-1.0.jar

通过日志形式输出

java -jar -XX:+PrintGCTimeStamps yeti-apiapp-1.0.jarjava -jar -XX:+PrintGCDateStamps yeti-apiapp-1.0.jar

输出GC详细日志到/usr/log方式

java -jar -Xloggc:/usr/log -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1024 yeti-apiapp-1.0.jar

通过脚本的方式获取GC数据

jstat -gcutil 13668 1000

垃圾收集算法

理解Throughput垃圾收集器

理解CMS垃圾收集器

理解G1垃圾收集器

堆内存最佳实践

查看堆直方图

jcmd 13668 GC.class_histogram

原生内存最佳实践

原生内存跟踪

原生内存跟踪 Native Memory Tracking

Java8开始可以查看原内存使用情况
-XX:NativeMemoryTracking=off|summary|detail summary=概要模式 detail=详细模式
通过jcmd命令获取原生内存信息 jcmd process_id VM.native_memory sumary

java -XX:NativeMemoryTracking=summary -jar yeti-apiapp-1.0.jarjcmd 16768 VM.native_memory summary

image-20210809163338632

Class - 保存类元数据

Thread - 66个线程,每一个大概1M空间

Code - JIT的代码缓存

Native Memory Tracking - NMT本身操作需要消耗一些内存

基线的使用

jcmd 16768 VM.native_memory baselinejcmd 16768 VM.native_memory summary.diff

image-20210809163438511

线程与同步的性能

对于线程的性能来说,并没有太多可以调优的地方,可以设置的JVM标志非常的少,而且这些标志的作用也非常小,比如说线程栈大小的调节、偏向锁的设置、自旋锁方式配置、线程优先级调节,是完全没有必要的,甚至进行调节之后对于程序的运行有很大的影响。

查看线程

jconsole 15784

image-20210809162811553

查看阻塞线程

jstack 15784

image-20210809162709457

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向高级工程师、架构师的必备技能,也是高薪、高职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、高并发和垃圾回收导致的CPU过高的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页高清PDF理论篇课件1份89页高清PDF实战篇课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论篇部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战篇部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值