4月15号在公司给大家分享了下Hotspot的内存管理和分析工具,以下是分享内容:
Java运行时数据区
HotSpot是JDK默认的虚拟机实现。
根据《Java虚拟机规范》,得知Java运行时数据区由下图组成:
- PC(program counter)寄存器:每一条 Java虚拟机线程都有自己的 PC(Program Counter)寄存器,PC 寄存器用于保存 Java 虚拟机正在执行非native方法的的字节码指令的地址。
- JVM Stack:java虚拟机栈,每一条 Java 虚拟机线程都有自己私有的 Java 虚拟机栈,java虚拟机栈用于存储栈帧。
- Native Method Stack:本地方法栈,用于非java语言的代码执行。
- Heap:堆用于存放所有实例对象以及数组对象,这部分内存由JVM通过GC管理内存回收。
- Method Area:方法区用于存放类的结构信息,包含运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容等
- Runtime Constant Pool:运行时常量池包括了若干种不同的常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用.
虚拟机栈
栈帧随着方法调用而创建,随着方法结束而销毁,栈帧中包含局部变量表,操作数栈,一个指向运行时常量池的引用。
局部变量表包含(boolean、byte、char、short、float、reference,long,double)采用索引的方式定位,发生带参数的方法调用时,创建新栈帧,参数会依次占用局部变量表。
操作数栈为一个LIFO的栈,Java 虚拟机提供一些字节码指令来从局部变量表或者对象实例的字段中复制常量或变量值到操作数栈中,也提供了一些指令用于从操作数栈取走数据、操作数据和把操作结果重新入栈。在方法调用的时候,操作数栈也用来准备调用方法的参数以及接收方法返回结果。
那么平时工作中能接触到栈帧么?答案是肯定的,如下图,在eclipse中debug的时候可以看见,每一个线程下面随着方法的调用,栈帧随之而创建,方法调用结束而销毁,下图红框部分即为栈帧。
通过以上介绍,大家应该对Java运行时数据区有个大致的了解了。
HotSpot内存管理
分代管理
有了对java运行时数据区的一个大概了解,我们就可以继续学习一下HotSpot的内存管理方面的知识了。
现代的虚拟机都将堆分代来管理,那为什么分代呢?分代的依据是什么?分代依据:weak generational hypothesis,即弱代假说:
- 大多数对象早死
- 老对象很少应用新对象
基于以上假说,HotSpot将堆分为新生代,老年代,而方法区由持久代实现。
新生代
由于新生代对象98%都是朝生夕死,故采用复制算法回收效率最高,将新生代分为一块Eden,二块Survivor区域。
Eden区域用于新对象的内存分配。Eden内存分配采用bump-the-pointer技术,使用一个指针指向已分配内存的末尾,分配内存时,仅检查剩余内存是否满足新对象分配。效率高。对于多线程内存分配采用Thread-Local Allocation Buffers TLABS,每个线程有自己的一块空闲内存分配缓冲区。不需要任何锁机制,只有当一个TLAB满了以后才需要同步
两块Survivor区域分为From和To,To区域用于下次新生代GC存活对象的存放地,From区域存放着至少活过一次新生代GC的对象。在一次新生代GC结束后,From变为To,To变为From,如下图所示
老年代
在新生代Survivor区域中活过若干代的对象将晋升至老年代。
大对象直接进入老年代。
在一次minorGC,survivor区域无法容纳时,剩余对象也会进入老年代。而当老年代满时,或者空间分配担保失败时会触发一次majorGC。
垃圾收集
什么是垃圾?
从GC ROOTS对象出发,不在GC roots引用链上的对象即为垃圾对象
那么哪些对象是GC roots对象呢?
虚拟机栈(栈帧中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。
垃圾收集器
串行收集器
串行收集器采用串行单线程的方式手机垃圾,新生代采用复制算法,老年代,持久代采用标记-整理算法。
并行收集器
如上图,Parallel Scavenge收集器是现在jdk1.6,jdk1.7,server模式下默认收集器
-XX:MaxGCPauseMillis最大GC收集时间以及-XX:GCTimeRatio GC收集时间占比。
CMS收集器
CMS全称Concurrent Mark Sweep,仅能用于老年代,持久代;
CMS如上图所示分为四个阶段:
第一阶段初始标记,仅标记gc root直接关联对象。
第二阶段,并发标记,通过第一阶段的标记对象追踪与GC root关联的对象
第三阶段,重新标记,修正并发期间标记产生变动的对象。
第四阶段,并发清除,清除不可达对象。
在第四阶段并发清除时不能保证清除掉这个阶段产生的垃圾对象,这些垃圾对象称为Floating Garbage。
由于是两个阶段都是并发执行,有可能就会出现一次GC未执行完时,老年代已经没有足够的空间容纳进入老年代的对象了,此种情况称之为Concurrent Mode Failure,当这种情况发生时,GC将stop-the-world直至此次收集结束。
G1
命令行分析工具
命令行分析工具应该是每个java程序员必须会用的工具,上图还未列举完整,如Jstack也比较常用。
可视化分析工具
Jconsole应该大家都是知道的,jvisualVM是一个多合一的分析工具,自带插件体系,不过可用插件不多。MAT是eclipse的一个插件,用于分析dump下来的java堆,可直观的看出是否有内存泄露,对象的信息,对象到GC root的引用链等信息。
案例分析
网站宕机
去年11月网站宕机大概几个小时,表现为resin假死无响应,通过监控宝看到宕机前活动线程增加至267个后,网站就无响应了。后重启resin恢复,但是在宕机后的几天观察到工作日早上10点,11点resin活动线程均莫名的往上窜,几次也导致网站挂掉。
分析:通过查看nginx日志,发现爬虫请求在第一次宕机前后有30%左右的增加,爬虫一般都爬的商品底层页,商品底层页也是服务器处理比较慢的地方。当时断定为爬虫导致网站宕机。处理办法就是将爬虫限制频率。但是后面也出现了挂掉的情况,后通过在挂掉时把当时的栈dump下来观察才发现是由于首页缓存人工清理掉后,再次加载导致的线程排队等待加载完成的情况导致活动线程数上升,从而导致resin无法创建新线程以响应请求导致的网站无响应,这也能解释之前重启后再次挂掉的情况。也能解释周末不发生此类情况,因为周末首页维护人员一般不会去主动去清除首页缓存。
加盟店商品同步
加盟店商品同步程序在早上时,服务器的负载经常彪至几十,但是通过重启应用,负载就下来了,原因貌似是应用运行久了以后越跑越慢了。
但是通过heapdump分析得出早上系统全量同步商品时,需要同步的数量太多,而此应用是将这些需要同步的商品每一个都new一个线程放入线程池中执行,负载高是因为此服务器上有7个这样的应用,每个应用开启了20个线程去执行每个应用自己的线程池。重启后,线程池中排队的线程肯定就被丢弃了,所以才有负载降低的现象。如果执行效率低还会造成队列越排越长,从而引发OOM。
此次的分享就到这个地方。
相关推荐
文中还列举了一些评估垃圾收集性能的工具,包括命令行选项–XX:+PrintGCDetails和–XX:+PrintGCTimeStamps、jmap、jstat、HPROF:堆分析器以及HAT:堆分析工具。第8节列出了与垃圾收集相关的关键选项。最后,文档...
### Java HotSpot虚拟机的内存管理 #### 一、引言 Java HotSpot虚拟机作为Sun Microsystems(现已被Oracle收购)开发的一款高性能JVM(Java虚拟机),在内存管理方面有着独特而强大的机制。本文旨在深入探讨Java ...
**jmap Eclipse内存分析工具详解** 在Java开发中,内存管理是至关重要的,尤其是在大型应用或者长时间运行的服务中,内存泄漏可能导致系统性能下降甚至崩溃。为了有效地检测和诊断内存问题,Oracle提供了`jmap`...
深入理解Hotspot源码,有助于开发者优化Java应用,理解内存管理、垃圾收集的工作原理,以及如何利用JVM工具进行性能调优。对于Java程序员来说,这是一门必不可少的进阶课程,能提升代码编写和问题排查的效率,使应用...
- **内存Dump**:使用MAT(Memory Analyzer Tool)等工具对内存快照进行分析,找出内存泄漏等问题。 ### 总结 HotSpot虚拟机作为Java生态系统中的核心组件之一,在现代软件开发中扮演着举足轻重的角色。通过深入理解...
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存...
RouterOS 5.x 配置 Hotspot 认证实现 UserManager 中文认证管理归类 RouterOS 5.x 配置 Hotspot 认证实现 UserManager 中文认证管理归类是 RouterOS 5.x 版本中的一种实现 Hotspot 认证的解决方案。该解决方案主要...
HotSpot的主要任务包括内存管理、垃圾收集、类加载、线程管理和性能优化。 2. **编译器策略**:HotSpot包含两种内置编译器——C1(Client Compiler)和C2(Server Compiler)。C1适用于启动速度,而C2则更注重长期...
总结来说,Hotspot JVM作为Java平台的核心,其源码揭示了Java程序执行的底层细节,包括垃圾收集、内存管理、线程调度、编译优化等多个重要方面。通过深入学习Hotspot源码,开发者可以更好地理解和优化Java应用程序,...
介绍了一系列用于评估垃圾收集性能的工具和命令行选项,包括打印垃圾收集详细信息的命令、jmap、jstat、HPROF和HAT等分析工具。 7. 与垃圾收集相关的关键选项 简要列举了影响垃圾收集器行为的一些关键选项。 8. 更...
#### HPROF:堆内存分析器 HPROF是一个强大的工具,可以提供详细的堆内存使用报告,包括对象实例数量、大小等信息。 #### HAT:堆分析工具 HAT工具用于分析堆转储文件,识别潜在的内存泄漏和其他问题。 ### 关键...
四、内存模型与内存管理 Hotspot虚拟机的内存模型包括新生代、老年代以及持久代。源代码中展示了如何分配和管理这些区域,以及如何处理对象晋升、内存碎片等问题。对于Java开发者来说,理解这些机制有助于避免内存...
5. 调优工具:HotSpot提供了诸如JConsole、VisualVM等强大的性能监控和调优工具,其源码可以帮助我们深入了解虚拟机的运行状态,进行性能瓶颈分析。 6. 编译优化:HotSpot的服务器模式(Server Mode)下,JIT编译器...
Eclipse Memory Analyzer(MAT)是一款强大的内存分析工具,可帮助定位内存泄漏,提供详细的内存泄漏报告和建议。 11. **JDK 6的相关内容** JDK 6在内存管理方面的一些特性,例如对GC算法的改进、内存分配策略等...
Hotspot源码的分析有助于开发者深入理解Java性能优化、内存管理以及垃圾收集机制。 首先,让我们探讨一下JVM。Java虚拟机是Java平台的核心组成部分,它为Java程序提供了一个跨平台的运行环境。Hotspot JVM是Oracle ...
生成堆转储文件后,我们通常会使用专门的内存分析工具来解析和分析这些数据,以发现可能存在的内存泄漏、过大对象或不合理的对象引用等问题。MAT(Memory Analyzer Tool)就是这样的一个强大的分析工具,它是Eclipse...
### Sun JVM原理与内存管理 #### 一、Sun JDK 1.6 GC (Garbage Collector) Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC...
本书深入浅出地讲解了 HotSpot 虚拟机的工作原理,将隐藏在它内部的本质内容逐一呈现在读者面前,包 括 OpenJDK 与 HotSpot 项目、编译和调试 HotSpot 的方法、HotSpot 内核结构、Launcher、OOP-Klass 对象表 示系统...