在双11之前,做了一些UMP GC优化的事情,和大家分享下问题查找和优化的思路。
一. 一些GC基础知识
1. 大部分jvm都有分代的概念,堆被分成2个部分,一个Young区,一个old区
2. -Xmx设置堆的最大值,-Xmn设置young区的大小,减一下就是old区的大小
3. Young区又分为Eden,survivor(s0,s1,大小通过SuvivorRatio指定)区,新生对象一般都在eden区分配,Hotspot为了优化对象创建的效率,给每个线程默认分配了部分内存TLAB,线程先在自己的TLAB空间创建对象,如果不够则去eden区分配。Survivor区是为了让生命周期短的对象尽量在young区就被回收掉,也就是每次young区执行gc之后,eden区和s0/s1中的一个都会被清空,只剩下s0/s1的一个存放对象
4. Hotspot的Young区gc有3种算法,Serial,ParNew,PS
5. 一般Young区触发gc的条件是eden区满
6. ParNew算法是stop-the-world的,也是说执行的时候所有用户线程会暂停
7. 更多gc知识可以毕玄大师的分享,http://www.docin.com/p-417999249.html
二. ParNewGC运行时间分析
1. Gc root
Young gc运行时,gc root一般是从线程的栈帧出发查找活跃对象,还有一个不可忽视的root是old区的对象,比如在运行期某个线程修改了某个old区对象的某个引用,则这个对象也需要作为gc root进行扫描以决定哪些young区的对象还活着,为了避免young gc时扫描整个old区,hotspot提供了dirty card机制来优化old区的扫描。
2. Dirty card
Hotspot将old区按512字节的page进行划分,存放到内部的dirty card列表中,当线程修改某一个old区对象的某个引用时,就会更新这个对象对应的dirtycard为’脏数据’。这样young gc的时候就需要扫描这些dirty page中的对象来决定young区哪些对象还活着。
3. 所以Young gc的时间,就可以这样表述: Tyoung =Tstack_scan + Tcard_scan +Told_scan+ Tcopy 。 Tstack_scan 是扫描线程栈找出活跃对象的时间,一般比较快。Tcard_scan 扫描dirtycard表的时间,取决于old区的大小。Told_scan 如果某一页page有脏数据,则把它作为gc root扫描,取决于old区的大小和具体业务是否有产生’脏数据’。Tcopy 是复制存活对象到s0/s1,更新引用地址的时间,取决于存活对象数量,大小。其中主要影响的时间是Told_scan+ Tcopy 。
三. UMP的jvm参数和gc方式
为了了解UMP应用的gc情况,我们先看下线上ump应用的启动参数: ps –ef|grep java
1. ump的堆设为4G,young区为1600m,suvivorRatio为10,则eden区大小为1600* (1-2/12)=1333.33M,s0=s1=133.33M
2. –XX:+UseConcMarkSweepGC,ump的old回收使用了cms算法,这样默认的young区的gc算法就是ParNew
3. –verbose:gc打印gc信息到gc.log。观察gc.log:
a. Young使用了ParNew算法,从图中可知,一次young gc之后,当时young区的gc从1400541K减少到了40011K(只在一个survivor区),ParNew耗时0.0267970s,可见每次young gc效率是很高的。
b. 1501888K是eden+s0或s1的大小
c. 当时jvm堆总大小从2254921K降到了895376k,总耗时0.0271140s
d. Gc时间在用户代码执行是0.11s,系统调用时间是0.00,真实时间是0.03s,可以看出这里ParNew是起了多线程来执行的
e. 可以通过jstack的线程信息看出ParNew的gc线程数量:
可以看出默认情况下jvm是起了和cpu数量一样的ParNew线程,ump是5个。
四. Young区诊断
一般情况下,young gc的频率是比较高的,每次new都会在eden区创建新的对象。当然young gc的频率太高,会对应用有影响,毕竟是stop-the-world,应用会停顿。当我们发现young gc频率太高了,我们就会想知道到底是哪些对象导致,会不会有大对象?会不会有多余的对象?我们需要找出这些对象,可以借助于一些工具。
1. Mat - http://www.eclipse.org/mat/
Eclipse的mat插件是分析java堆的神器。我们使用jmap dump内存,注意jmap会stop-the-world的:
sudo -u admin /opt/taobao/java/bin/jmap -histo 22314>>jmap
将这个dump文件拉下来,启动mat分析。但是不幸的是,默认的mat只会分析存活的对象,但是young区中其实有很多对象是dead的。这个时候我们就需要mat的一个扩展选项:
保留unreachable的对象,这样我们就可以看到有哪些对象是new了之后立马就变成unreachable了,这些对象是优化的重点。这个需要mat比较新的版本才有~~
a. 打开dominator_tree栏,可以看到当前堆里对象的分布,’unreachable’的就是那些临时对象,在mat里可以看到这些对象的属性和引用它的对象,比较容易发现问题J
b. Shallow heap指对象本生的大小,retained heap指该对象被回收之后将一块回收的那些对象的总大小(比如内部属性)
2. TBJmap -https://github.com/jlusdy/TBJMap
是叔同大师写的一个jmap扩展,基于Serviceability Agent实现,会阻塞应用,建议使用前先把应用offline。使用比较简单:
java -classpath/home/admin/tbjmap.jar:/java/lib/sa-jdi.jar sun.jvm.hotspot.tools.TBJMap -histoPID > jmap_output.log
可以看到哪些大对象占据了eden区
五. Young区优化
优化的主要目标是减少应用因为younggc带来的停顿时间,可以取一段时间的总停顿时间做为benchmark。
1. jvm系统层面
a. Eden调大,比如调大Xmn,或者调大SuvivorRatio以增大eden区容量,这样就可以存放更多的对象,减少young gc频率。但是代价是单次young gc的时间要变长,所以总停顿时间未必就会降低,需要反复实践。
b. 增加young gc线程,通过XX:ParallelGCThreads设置,默认是逻辑cpu个数,应该说这个值已经是合理的了,因为gc都是cpu-bound的任务,适当增加线程数未必会带来好的效果,不过可以增加cpu以提高并发度。
c. 调小TenuringThreshold,减少对象在young区的停留时间,将压力转移给old区J
2. 应用层面
a. 减少每次请求创建的对象数量,这里有很多代码技巧,最常见的:
1. 使用object cache
2. 熟悉各种Collection的原理和使用场景,如果可以预见容量,则设置初始容量,比如用hashmap,默认的数组大小是16,如果只有2个元素,则可以new HashMap(2)这样用。
3. 减少复杂对象包装,在jvm中一个对象的大小可以简单表述: header8+klassoop4(开启压缩指针,不开的话是8)+ sizeof(属性)+pading(可选),也就是说每个对象都有12个字节固定消耗,如果对象嵌套复杂的话,带来的消耗也就多了。
b. 降低tps,比如增加机器,流控等
六. 小结
本文简单介绍了,hotspotjvm下的young区性能诊断和优化。Young区的优化比较难做,更多的需要从业务上进行优化,我们平时在写业务代码的时候也要注意下对gc的影响~~
七. 资料
毕玄大神的gc分享,必看 http://www.docin.com/p-417999249.html
计算一个对象的大小 http://sizeof.sourceforge.net/
Shallow和retained大小解释 http://kenwublog.com/understand-shallow-and-retained-size-in-hprofling
Cms gc日志解读 https://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs
Mat手册 http://wiki.eclipse.org/index.php/MemoryAnalyzer
- 大小: 165.3 KB
- 大小: 13.1 KB
- 大小: 37 KB
- 大小: 28.8 KB
- 大小: 35 KB
- 大小: 82.5 KB
- 大小: 85 KB
- 大小: 59.7 KB
- 大小: 159.4 KB
分享到:
相关推荐
10. **JVM诊断工具**:JDK提供了丰富的命令行工具,如jps(Java进程查看)、jstat(统计JVM各种数据)、jmap(内存映射工具)、jhat(堆转储分析)、jconsole(GUI监控工具)等,用于监控和诊断JVM的运行状态。...
字节码的解析和执行由解释器和即时编译器(如HotSpot的C1和C2编译器)共同完成,实现解释执行与编译执行的混合模式。 3. **内存管理与垃圾回收**:JVM的内存管理主要涉及对象的分配与销毁,其中垃圾回收是核心部分...
Hotspot是Oracle JDK和OpenJDK中的一个JVM实现,以其高效性能和优化能力而著称。本文将深入探讨OpenJDK中的JVM Hotspot实现源码,帮助读者理解其内部机制和优化策略。 首先,Hotspot JVM的核心设计理念是“热Spot”...
6. **性能监控和调试工具**:书中可能包含如何使用JVisualVM、JConsole、JFR(Java Flight Recorder)和JMC(Java Mission Control)等工具来监控和诊断HotSpot虚拟机的状态。 7. **并行与并发**:HotSpot虚拟机...
Hotspot提供了丰富的性能监控和诊断工具,如jconsole、jmap、jstack等,这些工具的实现也是源码的一部分,有助于我们理解JVM的运行状态。 通过对JDK8u-hotspot源码的深入学习,开发者能够掌握JVM内部运作的核心...
9. **性能监控和调试**:提供了丰富的工具集,如JConsole、VisualVM等,帮助开发者诊断和优化应用性能。 学习OpenJDK Hotspot源码对于理解JVM的内部运作机制,优化Java应用程序,以及开发自定义JVM组件具有重要意义...
《深入解析Hotspot JVM源码》 Hotspot JVM,全称Hotspot Virtual Machine,是Java开发工具包(JDK)中的关键组成部分,负责运行...通过深入学习Hotspot源码,开发者可以更好地理解和优化Java应用程序,提升系统性能。
6. **性能监控和调试工具**:如JConsole、VisualVM等,可以帮助分析和诊断Hotspot虚拟机的运行状态,包括CPU、内存、线程等信息。 7. **动态编译优化**:如Profile-guided optimization(PGO)和On-stack ...
为了便于开发,JDK 1.8还包括了增强的调试工具,如JConsole和VisualVM,它们可以帮助开发者监控和诊断应用程序的性能问题。 总的来说,JDK 1.8是一个具有里程碑意义的版本,它的特性如Lambda表达式、Stream API、...
【标题】"hotspot-8.rar" 涉及的核心知识点是HotSpot虚拟机和JVM(Java Virtual Machine)的学习,这是一款由Oracle公司开发的Java虚拟机实现,广泛应用于Java程序的运行与优化。HotSpot是Java平台的重要组成部分,...
7. **性能监控和工具支持**:Hotspot提供了丰富的性能监控和诊断工具,如JConsole、VisualVM等。源码中包含了这些工具的接口和实现,位于`serviceability`和`diagnostic`目录。 通过深入研究Hotspot源码,开发者...
- **分代假设**:HotSpot基于对象存活时间的不同将其划分为年轻代和老年代,年轻代又细分为Eden区和Survivor区。 - **不同的垃圾回收算法**:包括Serial、ParNew、Parallel Scavenge、CMS、G1等不同类型的垃圾回收...
3. 性能监控和诊断:HotSpot提供了大量的JVM监控和诊断工具,例如jps、jstat、jmap、jstack和jcmd等命令行工具,以及基于Java Management Extensions(JMX)的图形用户界面工具,如JConsole和VisualVM,这些工具允许...
### HotSpot实战知识点详解 #### 一、HotSpot虚拟机简介 HotSpot 是一款高性能的 ...通过以上知识点的学习和实践,开发人员可以更深入地理解和优化基于 HotSpot 的 Java 应用程序,从而提升系统的整体性能和稳定性。
将隐藏在它内部的本质内容逐一呈现在读者面前,包 括 OpenJDK 与 HotSpot 项目、编译和调试 HotSpot 的方法、HotSpot 内核结构、Launcher、OOP-Klass 对象表 示系统、链接、运行时数据区、方法区、常量池和常量池 ...
2. 内存管理:HotSpot将内存分为堆(Heap)和非堆(Non-Heap)两部分,堆内存主要用于对象实例的存储,非堆内存则包含方法区和JVM自身的数据结构。源码中,`MemoryManager`与`GarbageCollector`密切合作,实现内存...
1. **热管理**:通过准确预测温度分布,Hotspot 可以帮助设计人员采取有效措施来降低芯片内部的热点温度,从而提高系统的稳定性和可靠性。 2. **能效优化**:通过对功耗的细致分析,设计者可以调整电路设计,以达到...
总的来说,Hotspot 1.6源代码的学习将帮助我们深入了解Java运行时环境的内部工作机制,提高程序设计和优化的水平。通过对这些源代码的深度阅读和分析,开发者可以更好地应对性能挑战,创造出更高效、更稳定的Java...
5. 测试和优化:对 HotSpot 环境进行测试和优化,确保应用程序的性能和稳定性。 注意事项 1. JVM 参数的差异:JRockit 和 HotSpot 的 JVM 参数不同,需要注意参数的迁移。 2. 垃圾回收器的差异:JRockit 和 ...