JVM内存分析工具及注意事项

分析工具

jprofiler

官网  收费

Java Profiler - JProfiler

JProfiler's intuitive UI helps you resolve performance bottlenecks,
pin down memory leaks and understand threading issues.

jprofiler 提供了简单易用的UI界面,帮助解决性能问题,确定内存泄漏,解决线程问题。

When it comes to profiling, only the best tool is good enough.

只有准备好了 优秀的工具,才是足够好。

可以看出,jprofiler 的定位:是一款 简单好用的 内存分析工具。

jprofiler 可以看到实施的内存、GC、CPU、线程的活动状态,UI界面也比较友好。就是 收费

jvisualvm.exe、jconsole.exe

这两是 JDK自带的 内存检测工具。只是 UI界面 不太友好。

jprofiler 可以算是 这两的 升级版本。

MAT Memory Analyzer Tool

下载地址:

Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

分析 JVM dump 文件 最好的工具。他可以 根据 dump文件 ,提示出 可能存在的问题,比如 哪些对象占用过多,并且可以分析出这些过多内存的 引用路径,对于分析问题 非常有帮助

注意事项:

1. jprofiler 实时内存 显示的对象 个数,是包含 存活对象和非存活对象的。 如果对象引用不可达,但是此时 没有发生GC时,也会被统计到对象个数中。

跟 jmap -histo pid 统计的数据一致。

2. jvisualvm.exe 工具自带了一个 dump按钮,如果点击了 Dump按钮,会触发一次GC活动

3. MAT Memory Analyzer Tool 分析工具,分析的dump文件,可能是只包含存活对象

就目前知道的 jmap -dump 命令 生成的 dump 文件,是只包含存活对象,即使 不存活的对象没有被GC回收,也不会输出到dump文件

4. 分析内存占用过的

内存占用过的,是一种结果。导致这个结果的原因:

1.  仍然存活的 对象 占据的内存

2. 已经die的对象 占据的内存

die的对象 占据的内存 会在未来某个时间 被GC 回收。

如果确定存活的对象 占据内存 依然居高不下,就要考虑:

1. 确实 需要 创建这些大量的对象,这种原因的话,就需要 避免 需要创建大量对象的 情况发生

2. 发生了 内存泄漏

所以,如果JVN内存占用过多,可能是 GC 没有触发,导致 引用不可达的对象 没有及时被回收。如果 用 jprofiler 分析问题的话,需要关注 GC 活动情况。如果GC后,内存仍然占用过的,就需要具体分析是否内存泄漏还是其他问题。

### Java 垃圾回收中标记存活对象的方法 在Java虚拟机(JVM)中,垃圾回收器通过特定的算法来区分哪些对象是活动的(即仍被引用),哪些是可以回收的。对于标记存活对象的过程,主要依赖于可达性分析算法[^3]。 #### 可达性分析算法原理 该算法从一系列称为“GC Roots”的根节点集合出发,按照图论中的连通理论遍历整个对象图结构。只要是从这些根节点开始能够到达的对象都被认为是活跃状态;反之,则会被视为可回收对象。典型的GC Roots成员包括但不限于: - 正在执行方法中的局部变量表内的引用; - 所有类静态属性所持有的引用; - 运行时常量池里的引用; - 本地方法栈中JNI(Native方法)持有者们的引用。 一旦确定了GC Roots之后,JVM会采用不同的策略去追踪并标记那些可以从这些起点访问到的对象。这一步骤通常发生在所谓的“Stop The World”事件期间,在此过程中应用程序的所有线程都会暂时停止以便让GC安全地完成其工作而不受干扰[^4]。 #### 实际操作过程 当触发一次完整的垃圾收集周期时,具体的操作流程如下所示: 1. **初始化阶段**:准备必要的数据结构用于记录已扫描过的对象以及待处理队列。 2. **标记阶段**:从GC Roots开始递归地标记每一个可以直接或间接触及的目标实例,并将其加入到已知存活列表里。 3. **清理阶段**:依据前面两个步骤的结果决定哪些区域应该释放给后续分配新对象使用。 ```java // 示例代码展示了一个简单的模拟场景,其中包含了创建对象和显式调用System.gc() class TestGC { public static void main(String[] args) throws InterruptedException { Object objA = new Object(); Object objB = new Object(); // 创建一些临时对象供测试用 for (int i = 0; i < 10000; ++i) { new Object(); } Thread.sleep(500); // 给予足够的时间使上述短生命周期对象成为候选回收目标 System.gc(); // 请求进行垃圾回收 } } ``` 这段程序展示了如何利用`System.gc()`建议启动一次全局范围内的垃圾搜集动作,尽管实际效果取决于当前使用的垃圾收集器配置及其内部逻辑实现[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值