`

探究JVM内存泄露

 
阅读更多

WEB 服务总是莫名其妙的运行一段时间后 JVM 直接 OutOfMemory 错误,内存泄漏的问题不容易查找,本文就一些查找内存泄露基本知识做个总结,未涉及到具体案例的分析。

1          JVM 内存异常的数据显示
1.1        java.lang.OutOfMemoryError: PermGen space 异常的例子

 

Heap 
PSYoungGen       total 44928K, used 916K [0x4e3c0000, 0x50fe0000, 0x51b10000) 
  eden space 44736K, 2% used [0x4e3c0000,0x4e4a5318,0x50f70000) 
  from space 192K, 0% used [0x50f70000,0x50f70000,0x50fa0000) 
  to  space 192K, 0% used [0x50fb0000,0x50fb0000,0x50fe0000) 
PSOldGen         total 453312K, used 125529K [0x32910000, 0x4e3c0000, 0x4e3c0000)
  object space 453312K, 27% used [0x32910000,0x3a3a6498,0x4e3c0000) 
PSPermGen       total 65536K, used 65535K [0x2e910000, 0x32910000, 0x32910000) 
  object space 65536K, 99% used [0x2e910000,0x3290fff8,0x32910000)

permanent space 持久空间 用于类和方法对象的存储。 spring  AOP 时使用 CBLIB 会动态产生很多类,当类太多,超过 MaxPermSize 的时候,就会抛出此异常。 参数问题 可以设置 jvm 启动参数 : PermSize, MaxPermSize 。程序问题就要进行内存分析了,详见下文。

1.2        java.lang.OutOfMemoryError: Java heap space 异常的例子

 

Heap
PSYoungGen total 88320K, used 67673K [0x44880000, 0x4ba40000, 0x4ba40000)
eden space 61952K, 100% used [0x44880000,0x48500000,0x48500000)
from space 26368K, 21% used [0x48500000,0x48a96490,0x49ec0000)
to space 24512K, 16% used [0x4a250000,0x4a6283e0,0x4ba40000)
PSOldGen total 932096K, used 582090K [0x0ba40000, 0x44880000, 0x44880000)
object space 932096K, 62% used [0x0ba40000,0x2f2b2a78,0x44880000)
PSPermGen total 131072K, used 35124K [0x03a40000, 0x0ba40000, 0x0ba40000)
object space 131072K, 26% used [0x03a40000,0x05c8d330,0x0ba40000)

eden space 使用率 100% ,总是被占满,参数问题 可以设置 jvm 启动参数 : Xms, Xmx 。程序问题就要进行内存分析了,详见下文。

1.3        查看 jvm 内存状态:

jstat -gcutil pid 1000 20

异常情况的例子

jstat -gcutil pid 1000 20

 

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
  0.00   0.00  99.99  82.51  53.11   2409    1.205 10117 7250.393 7251.598
  0.00   0.00  83.42  82.55  53.10   2409    1.205 10118 7252.650 7253.855
  0.00   0.00  56.06  82.46  53.10   2410    1.205 10120 7254.467 7255.672
  0.00   0.00  32.11  82.55  53.10   2411    1.205 10121 7256.673 7257.877
  0.00   0.00  99.99  82.55  53.10   2412    1.205 10123 7257.026 7258.231
  0.00   0.00  76.00  82.50  53.10   2412    1.205 10124 7259.241 7260.446

这个数据显示 Full GC 频繁发生。

 

正常情况的例子

 

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

  0.00   0.00   0.24  55.39  99.60    171    0.667  1339  393.364  394.031

参数含义: 
S0
  Heap 上的 Survivor space 0 段已使用空间的百分比 
S1
  Heap 上的 Survivor space 1 段已使用空间的百分比 
E
  Heap 上的 Eden space 段已使用空间的百分比 
O
  Heap 上的 Old space 段已使用空间的百分比 
P
  Perm space 已使用空间的百分比 
YGC
 :从程序启动到采样时发生 Young GC 的次数 
YGCT
  Young GC 所用的时间 ( 单位秒 
FGC
 :从程序启动到采样时发生 Full GC 的次数 
FGCT
  Full GC 所用的时间 ( 单位秒 
GCT
 :用于垃圾回收的总时间 ( 单位秒 )

2          Dump 出内存
2.1        找出要 dump 的线程 pid

 

 windows 下,使用 tasklist

 Linux 下,使用 ps –aux

2.2        Dump 出内存使用详情

可以通过命令:

 

jmap -dump:file=a.hprof pid

也可以通过 jconsole 的图形界面操作。

 

在命令行键入: jconsole

Jconsole 打开后在造作下选择 dumpHeap, 输入参数 p0,p1;p0 表示 dump 出来的文件路径,后缀为 .hprof p1 设为 true ,表示只分析活着的对象。

 

3          使用内存分析工具

目前有很多用来分析 Java 内存对象的工具,如收费的工具有 jprofiler, 而像 Eclipse MAT 则是优秀的内存对象分析开源工具 . 它们对于分析内存溢出问题非常有用。以下是一个安装使用 Eclipse MAT 的简单例子。

3.1        装一个 Eclipse 的内存分析插件 MAT

http://download.eclipse.org/technology/mat/latest/update-site/

 

3.2        切换到 Memory Analysis 模式

 

3.3        通过 File > Open Heap Dump.... 查看 dump 出来的文件

 

 

4          JDK 自带的 JVM 查看分析工具 jps  jmap  jstat  jconsole
4.1        jps

Java 进程查看工具,实际上它和 Unix/Linux 上面的 ps 命令的功能差不多

4.2        jmap

jmap 是一个可以输出所有内存中对象的工具 .

* -dump:format=b,file=<filename>  转存堆内存到本地文件。 
  * -histo 
打印堆里每个类的情况,包含内存占用大小、对象数量及完整类名。 VM 的内部类以 "*" 开头。

例子:

 

jmap -histo pid>a.log

jmap -dump: file=a.hprof pid

查看 a.log

 

num   #instances    #bytes class name
--------------------------------------
1:    427398    14458448 [I
2:    178798     6830216 [C
3:     50278     6668512 <constMethodKlass>
4:    179924     4318176 java.lang.String
5:     50278     4026648 <methodKlass>
6:     15244     3894200 [B
7:     47809     1773776 [Ljava.lang.Object;
...
Total 1645187    81806088

说明:

#instance 是对象的实例个数 
#bytes 
是总占用的字节数 
class name 
对应的就是 Class 文件里的 class 的标识 
B 
代表 byte
C
 
代表 
char
D
 
代表 
double
F
 
代表 
float
I
 
代表 
int
J
 
代表 
long
Z
 
代表 
boolean
前边有 [ 代表数组, [I 就相当于 int[]

对象用 [L+ 类名表示

4.3          jstat

jstat  vm 的状态监控工具,监控的内容有类加载、运行时编译及 GC 

使用时,需加上查看进程的进程 id ,和所选参数。以下详细介绍各个参数的意义。   
    jstat -class pid:
 显示加载 class 的数量,及所占空间等信息。   
    jstat -compiler pid:
 显示 VM 实时编译的数量等信息。   
    jstat -gc pid:
 可以显示 gc 的信息,查看 gc 的次数,及时间。其中最后五项,分别是 young gc 的次数,young gc 的时间, full gc 的次数, full gc 的时间, gc 的总时间。   
    jstat -gccapacity:
 可以显示, VM 内存中三代( young,old,perm )对象的使用和占用大小,如: PGCMN显示的是最小 perm 的内存使用量, PGCMX 显示的是 perm 的内存最大使用量, PGC 是当前新生成的 perm 内存占用量, PC 是但前 perm 内存占用量。其他的可以根据这个类推, OC  old 内纯的占用量。   
    jstat -gcnew pid:new
 对象的信息。   
    jstat -gcnewcapacity pid:new
 对象的信息及其占用量。   
    jstat -gcold pid:old
 对象的信息。   
    jstat -gcoldcapacity pid:old
 对象的信息及其占用量。   
    jstat -gcpermcapacity pid: perm
 对象的信息及其占用量。   
    jstat -util pid:
 统计 gc 信息统计。   
    jstat -printcompilation pid:
 当前 VM 执行的信息。   
    
除了以上一个参数外,还可以同时加上 两个数字,如: jstat -printcompilation 3024 250 6 是每 250毫秒打印一次,一共打印 6 次,还可以加上 -h3 每三行显示一下标题。   
例子:

 

jstat -gcutil pid 1000 20

4.4        jconsole

一个 java GUI 监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器 VM    

 

 

http://blog.csdn.net/ajian005/article/details/6454660

分享到:
评论

相关推荐

    MAT JVM 内存分析工具.

    MAT JVM内存分析工具有以下几个核心功能和知识点: 1. **快照分析**:用户可以创建JVM进程的内存快照,这包含了运行时的所有对象和它们之间的引用关系。快照可以保存以便后续分析,这对于远程服务器或不再运行的...

    33、JVM探究.pdf

    【JVM探究】 Java虚拟机(JVM)是Java编程语言的核心组成部分,它负责执行Java程序,提供了一个跨平台的运行环境。理解JVM的工作原理对于优化Java应用程序性能至关重要。以下是一些关于JVM的关键知识点: 1. **JVM...

    JVM原理.pdf

    垃圾回收(Garbage Collection,GC)是JVM内存管理的一部分,它自动释放不再使用的对象占用的内存空间,以防止内存泄漏和内存溢出。常见的垃圾回收算法包括标记-清除算法、复制算法、标记-整理算法和分代收集算法等...

    monkey老师的jvm 调优

    Monkey老师的JVM调优课程,无疑为我们提供了一个宝贵的平台,来深入探究JVM的工作原理及其优化技巧。下面,我们就一起来深入学习Monkey老师关于JVM调优的核心知识点。 首先,我们要明白JVM的重要性。它是Java程序...

    JVM实战-对象访问与内存溢出异常解析

    通过本实验,旨在深入理解JVM内存管理机制以及各种内存区域的特点,并通过具体的编程实践来触发并分析这些异常,进而提升对Java应用程序性能调优和故障排查的能力。 #### 实验目标 1. **理解内存区域与内存区域...

    jvm理解pdf

    《深入理解Java虚拟机:JVM高级特性与最佳实践》这本书是Java开发者深入探究JVM(Java Virtual Machine)的重要参考资料。JVM作为Java程序运行的基础,它的理解和优化对于提升Java应用性能至关重要。以下将详细阐述...

    jvm 深入讲解

    内存泄露通常由于对象生命周期管理不当导致,可能导致系统资源耗尽。 6. **JVM调优**:JVM参数调整是优化性能的关键。例如,通过-Xms和-Xmx设置堆大小,-XX:NewRatio调整新生代和老年代比例,-XX:+...

    java高级技能全体系知识结构梳理全景图

    其次,Java高级学习还包括对JVM(Java虚拟机)的深入探究,包括JVM内存模型、类加载机制、性能调优等。掌握这些,能帮助开发者优化应用程序,提升运行效率。 1. JVM内存模型:理解堆、栈、方法区、本地方法栈等内存...

    GCT代码

    3. **JVM内存模型**:了解堆内存、方法区、栈内存等不同部分的作用,以及它们如何配合GC工作。 4. **源码分析**:通过阅读和理解JVM的GCT源码,深入探究其工作流程和决策机制。 5. **性能工具**:学习使用JVM提供...

    探究C语言和Java语言中垃圾回收的不同方式.pdf

    当程序不再使用某部分内存时,忘记调用free()函数去释放它,就会导致内存资源无法回收,这种情况累积多了,就会造成内存泄漏,最终可能导致整个程序因资源耗尽而崩溃。 C语言中偶尔会使用保守垃圾收集器...

    Java 堆内存溢出原因分析

    要理解和解决这个问题,我们需要深入探究Java内存管理机制,特别是堆内存的分配与回收。 首先,Java堆内存是Java虚拟机(JVM)中用于存储对象实例的主要内存区域。当程序创建大量对象,且这些对象生命周期较长,...

    MemoryAnalyzerTool(MAT)win版64位

    2. **OQL查询**:MAT支持OQL(Object Query Language),允许用户自定义查询,深入探究内存细节。 3. ** Leak Suspects Report**:此报告会自动识别可能导致内存泄漏的模式,是初学者的得力助手。 总结,MAT作为一...

    placeholder

    【标题】: "深入理解Java虚拟机:JVM内存管理和性能优化" 【描述】: "本资料详尽探讨了Java虚拟机(JVM)的工作原理,重点在于内存管理与性能优化。通过学习,读者将能够了解JVM的内存区域划分,如堆、栈、方法区等...

    圣思园张龙java开发进阶视频网盘.txt

    - **内存泄漏诊断**:定位内存泄漏的原因,使用`MAT`等工具进行分析。 - **JVM参数调优**:掌握关键参数如`-Xms`、`-Xmx`、`-XX:+UseConcMarkSweepGC`等的作用及合理设置方法。 - **JIT编译器**:了解JIT编译原理...

    Java虚拟源代码.zip

    5. **垃圾收集**:Java的自动内存管理机制,JVM负责识别不再使用的对象并回收其占用的内存,以防止内存泄漏。 6. **多线程支持**:JVM内置了对多线程的支持,每个线程都有自己的虚拟机栈和程序计数器。 7. **内存...

    2019互联网面试题第2季.mmap.zip

    1. **JVM内存模型**:理解堆、栈、方法区、本地方法栈、程序计数器等区域的作用,以及内存溢出问题的排查与解决。 2. **对象创建与内存分配**:探究对象在JVM中的创建过程,了解新生代、老年代、持久代的内存分配...

    基于计算机应用软件开发的Java编程语言探究.zip

    3. 自动内存管理:Java提供垃圾回收机制,自动管理内存,避免了内存泄漏问题。 4. 安全性:Java具有严格的类型检查和安全管理机制,有效防止恶意代码执行。 5. 多线程:Java内置多线程支持,便于实现并发操作。 6. ...

    Java虚拟机规范(Java SE 7)

    Java虚拟机规范(Java SE 7)是Java开发的关键组成部分,它是Java程序运行的基础,确保了跨平台的...阅读《Java虚拟机规范(Java SE 7)》这本书,可以进一步探究JVM的内部细节,为成为高级Java开发者奠定坚实基础。

    mat java 分析 文件 dump

    对于`quartz`任务调度框架而言,如果在Dominator Tree中发现其占据了较大的内存比例(例如10%),则需要深入探究是否有不合理的地方导致内存消耗过大。 ##### 3. Top Consumers **定义:** Top Consumers视图列出...

Global site tag (gtag.js) - Google Analytics