- 浏览: 115434 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (98)
- java (27)
- jms (2)
- jta (0)
- 性能调优及内存分析 (4)
- 设计模式 (14)
- 框架 (6)
- 其它 (9)
- job (1)
- maven (1)
- 服务器 (2)
- 分布式 (3)
- ibatis (1)
- linux (0)
- mysql (0)
- 并发编程 (0)
- java多线程 (2)
- 前端跨域 (1)
- 线程dump分析 (0)
- velocity (0)
- 数据库 (2)
- 协议 (0)
- 监控 (0)
- 开源软件 (2)
- 算法 (0)
- 网络 (1)
- spring (1)
- 编码 (0)
- 数据结构 (0)
- HTable和HTablePool使用注意事项 (0)
- opencms (0)
- android (16)
- 操作系统 (2)
- top (0)
最新评论
-
hold_on:
@Override public boolea ...
android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片) -
achersnake:
123
Servlet中listener(监听器)和filter的总结 -
angel243fly:
我用了这个方法,还是报同样的错误,还有什么建议吗?
eclipse提示CreateProcess error=87错误的解决方法
转: http://www.blogjava.net/rosen/archive/2010/05/21/321575.html
为什么用
MAT
之前的观点,我认为使用实时
profiling/monitoring
之类的工具,用一种非常实时的方式来分析哪里存在内存泄漏是很正确的。年初使用了某
profiler
工具测试消息中间件中存在的内存泄漏,发现在吞吐量很高的时候
profiler
工具自己也无法响应,这让人很头痛。后来了解到这样的工具本身就要消耗性能,且在某些条件下还发现不了泄漏。所以,分析离线数据就非常重要了,
MAT
正是这样一款工具。
为何会内存溢出
我们知道
JVM
根据
generation(
代
)
来进行
GC
,根据下图所示,一共被分为
young generation(
年轻代
)
、
tenured generation(
老年代
)
、
permanent generation(
永久代
, perm gen)
,
perm gen
(或称
Non-Heap
非堆)是个异类,稍后会讲到。注意,
heap
空间不包括
perm gen
。
绝大多数的对象都在
young generation
被分配,也在
young generation
被收回,当
young generation
的空间被填满,
GC
会进行
minor collection(
次回收
)
,这次回收不涉及到
heap
中的其他
generation
,
minor collection
根据
weak generational hypothesis(
弱年代假设
)
来假设
young generation
中大量的对象都是垃圾需要回收,
minor collection
的过程会非常快。
young generation
中未被回收的对象被转移到
tenured generation
,然而
tenured generation
也会被填满,最终触发
major collection(
主回收
)
,这次回收针对整个
heap
,由于涉及到大量对象,所以比
minor collection
慢得多。
JVM
有三种垃圾回收器,分别是
throughput collector
,用来做并行
young generation
回收,由参数
-XX:+UseParallelGC
启动;
concurrent low pause collector
,用来做
tenured generation
并发回收,由参数
-XX:+UseConcMarkSweepGC
启动;
incremental low pause collector
,可以认为是默认的垃圾回收器。不建议直接使用某种垃圾回收器,最好让
JVM
自己决断,除非自己有足够的把握。
Heap
中各
generation
空间是如何划分的?通过
JVM
的
-Xmx=n
参数可指定最大
hea
p
空间,而
参数
默认值
MinHeapFreeRatio
40
MaxHeapFreeRatio
70
-Xms
3670k
-Xmx
64m
由于
tenured generation
的
major collection
较慢,所以
tenured generation
空间小于
young generation
的话,会造成频繁的
major collection
,影响效率。
Server JVM
默认的
young generation
和
tenured generation
空间比例为
1:2
,也就是说
young generation
的
eden
和
survivor
空间之和是整个
heap
(当然不包括
perm gen
)的三分之一,该比例可以通过
-XX:NewRatio=n
参数来控制,而
Client JVM
默认的
-XX:NewRatio
是
8
。至于调整
young generation
空间大小的
NewSize=n
和
MaxNewSize=n
参数就不讲了,请参考后面的资料。
young generation
中幸存的对象被转移到
tenured generation
,但不幸的是
concurrent collector
线程在这里进行
major collection
,而在回收任务结束前空间被耗尽了,这时将会发生
Full Collections(Full GC)
,整个应用程序都会停止下来直到回收完成。
Full GC
是高负载生产环境的噩梦
……
现在来说说异类
perm gen
,它是
JVM
用来存储无法在
Java
语言级描述的对象,这些对象分别是类和方法数据(与
class loader
有关)以及
interned strings(
字符串驻留
)
。一般
32
位
OS
下
perm gen
默认
64m
,可通过参数
-XX:MaxPermSize=n
指定,
JVM Memory Structure
一文说,对于这块区域,没有更详细的文献了,神秘。
回到问题“为何会内存溢出?”。
要回答这个问题又要引出另外一个话题,既什么样的对象
GC
才会回收?当然是
GC
发现通过任何
reference chain(
引用链
)
无法访问某个对象的时候,该对象即被回收。名词
GC Roots
正是分析这一过程的起点,例如
JVM
自己确保了对象的可到达性
(
那么
JVM
就是
GC Roots)
,所以
GC Roots
就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常
GC Roots
是一个在
current thread(
当前线程
)
的
call stack(
调用栈
)
上的对象(例如方法参数和局部变量),或者是线程自身或者是
system class loader(
系统类加载器
)
加载的类以及
native code(
本地代码
)
保留的活动对象。所以
GC Roots
是分析对象为何还存活于内存中的利器。
知道了什么样的对象
GC
才会回收后,再来学习下对象引用都包含哪些吧。
从最强到最弱,不同的引用(可到达性)级别反映了对象的生命周期。
l
Strong Ref(
强引用
)
:通常我们编写的代码都是
Strong Ref
,于此对应的是强可达性,只有去掉强可达,对象才被回收。
l
Soft Ref(
软引用
)
:对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有
Strong Ref
时才回收对象。一般可用来实现缓存,通过
java.lang.ref.SoftReference
类实现。
l
Weak Ref(
弱引用
)
:比
Soft Ref
更弱,当发现不存在
Strong Ref
时,立刻回收对象而不必等到内存吃紧的时候。通过
java.lang.ref.WeakReference
和
java.util.WeakHashMap
类实现。
l
Phantom Ref(
虚引用
)
:根本不会在内存中保持任何对象,你只能使用
Phantom Ref
本身。一般用于在进入
finalize()
方法后进行特殊的清理过程,通过
java.lang.ref.PhantomReference
实现。
有了上面的种种我相信很容易就能把
heap
和
perm gen
撑破了吧,是的利用
Strong Ref
,存储大量数据,直到
heap
撑破;利用
interned strings
(或者
class loader
加载大量的类)把
perm gen
撑破。
关于
shallow size
、
retained size
Shallow size
就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。在
32
位系统上,对象头占用
8
字节,
int
占用
4
字节,不管成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为
null
它始终占用
4
字节。故此,对于
String
对象实例来说,它有三个
int
成员(
3*4=12
字节)、一个
char[]
成员(
1*4=4
字节)以及一个对象头(
8
字节),总共
3*4 +1*4+8=24
字节。根据这一原则,对
String a=”rosen jiang”
来说,实例
a
的
shallow size
也是
24
字节(很多人对此有争议,请看官甄别并留言给我)。
Retained size
是该对象自己的
shallow size
,加上从该对象能直接或间接访问到对象的
shallow size
之和。换句话说,
retained size
是该对象被
GC
之后所能回收到内存的总和。为了更好的理解
retained size
,不妨看个例子。
把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点
GC Roots
,正解!这就是
reference chain
的起点。
从
obj1
入手,上图中蓝色节点代表仅仅只有通过
obj1
才能直接或间接访问的对象。因为可以通过
GC Roots
访问,所以左图的
obj3
不是蓝色节点;而在右图却是蓝色,因为它已经被包含在
retained
集合内。
所以对于左图,
obj1
的
retained size
是
obj1
、
obj2
、
obj4
的
shallow size
总和;右图的
retained size
是
obj1
、
obj2
、
obj3
、
obj4
的
shallow size
总和。
obj2
的
retained size
可以通过相同的方式计算。
Heap Dump
heap dump
是特定时间点,
java
进程的内存快照。有不同的格式来存储这些数据,总的来说包含了快照被触发时
java
对象和类在
heap
中的情况。由于快照只是一瞬间的事情,所以
heap dump
中无法包含一个对象在何时、何地(哪个方法中)被分配这样的信息。
在不同平台和不同
java
版本有不同的方式获取
heap dump
,而
MAT
需要的是
HPROF
格式的
heap dump
二进制文件。想无需人工干预的话,要这样配置
JVM
参数:
-XX:-HeapDumpOnOutOfMemoryError
,当错误发生时,会自动生成
heap dump
,在生产环境中,只有用这种方式。如果你想自己控制什么时候生成
heap dump
,在
Windows+JDK6
环境中可利用
JConsole
工具,而在
Linux
或者
Mac OS X
环境下均可使用
JDK5
、
6
自带的
jmap
工具。当然,还可以配置
JVM
参数:
-XX:+HeapDumpOnCtrlBreak
,也就是在控制台使用
Ctrl+Break
键来生成
heap dump
。由于我是
windows+JDK5
,所以选择了
-XX:-HeapDumpOnOutOfMemoryError
这种方式,更多配置请参考
MAT Wiki
。
参考资料
Strong,Soft,Weak,Phantom Reference
Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine
Understanding Weak References译文
-Xms=n
则是指定
最小
heap
空间。在
JVM
初始化的时候,如果最小
heap
空间小于最大
heap
空间的话,如上图所示
JVM
会把未用到的空间标注为
Vi
rtual
。除了这两个参数还有
-XX:MinHeapFreeRatio=n
和
-XX:MaxHeapFreeRatio=n
来分别控制最大、最小的剩余空间与活动对象之比例。在
32
位
Solaris SPARC
操作系统下,默认值如下,在
32
位
windows xp
下,默认值也差不多。
发表评论
-
公钥,私钥和数字签名这样最好理解
2012-12-04 13:01 0一、公钥加密 假设一下,我找了两个数字,一个是1,一个是2 ... -
btrace学习二--btrace一个简单例子
2012-11-09 16:28 0btrace安装好了,就看一些语法吧。可以到btrace的官方 ... -
Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)
2012-10-25 20:27 0【目录】 一、【基础知识——扫盲】 二、【DOM、S ... -
如何在文件末尾写入新数据,适用JavaNIO
2012-07-02 09:29 1729转:http://stoneli88.iteye.com/bl ... -
BTrace使用简介
2012-05-23 16:23 937转:http://rdc.taobao.com/team/ ... -
java初始化顺序
2012-05-14 15:39 0转:http://www.cnblogs.com/miniwi ... -
HTMLDecoder,&#开头的编码换转成中文
2012-05-11 10:06 1153转:http://blog.sina.com.cn/s/blo ... -
类初始化顺序
2012-04-09 17:33 0转:http://www.cnblogs.com/miniwi ... -
Heritrix的eclipse配置启动
2012-04-07 11:46 0转:http://blog.csdn.net/lifesoft ... -
执行Runtime.exec异常: error=12,Cannot allocate memory
2012-03-26 10:03 1289转:http://blog.csdn.net/chifen ... -
使用Memory Analyzer tool(MAT)分析内存泄漏(二) ZZ
2012-03-13 08:41 1218http://www.blogjava.net/rose ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-03-12 12:52 0最近的机器内存又爆满了,除了新增机器内存外,还应该好好revi ... -
Java内存模型
2012-02-23 19:57 0(原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来 ... -
Runnable、Callable、Executor、Future关系解读
2012-02-22 10:02 0在再度温习Java5的并发编程的知识点时发现,首要的就是把Ru ... -
HashCode本质
2012-02-22 09:05 01.hashcode是用来查找的, ... -
Java并发--任务执行.
2012-02-17 19:40 0PS: 发到博客的文章竟然发布不到论坛, 所以将文章从博客 ... -
java并发编程-Executor框架
2012-02-17 19:39 0Executor框架是指java 5中引入的一系列并发库中 ... -
Java 并发核心编程
2012-02-17 16:28 0内容涉及: 1、关于java ... -
future使用
2012-02-17 14:53 0在Java中,如果需要设 ... -
常用 Java 静态代码分析工具的分析与比较
2012-02-16 14:20 0转:http://www.ibm.com/develope ...
相关推荐
MAT是分析Java堆内存的一个工具,全称是 The Eclipse Memory Analyzer Tool,用来帮助分析内存泄漏和减少内存消耗。使用MAT分析Java堆快照,可以快速计算出对象的保留大小(Retained Sizes),查找到阻止对象被回收...
MAT 是一个开源的java内存分析工具,能够快速的分析dump文件,可以直观的看到各个对象在内存占用的量大小,以及类实例的数量,对象之间的引用关系,找出对象的GC Roots相关的信息,此外还能生成内存泄露报表,疑似...
Memory Analyzer Tool,简称MAT,是Oracle公司开发的一款强大的Java内存分析工具,专用于诊断和优化Java应用的内存使用情况。MAT独立版为Mac用户提供了在操作系统环境下独立运行的版本,方便开发者对Mac平台上的Java...
通过本次使用 Eclipse Memory Analyzer (MAT) 分析 Tomcat 内存溢出的过程,我们可以得出以下结论: - 内存管理对于 Java 应用程序至关重要。 - 遇到内存溢出或泄露问题时,MAT 是一款非常强大的工具,可以帮助快速...
MAT(Memory Analyzer Tool)是Eclipse项目开发的一款强大的Java内存分析工具,主要用于诊断Java应用程序的内存泄漏和性能问题。在标题中提到的“Eclipse Memory Analyzer Version 1.7.0.rar”是一个压缩包,其中...
内存分析是Java应用程序性能优化的关键环节,而Memory Analyzer Tool (MAT) 是IBM开发的一款强大的内存分析工具,专门用于诊断Java应用程序中的内存泄漏和性能问题。MAT不仅提供了详细的内存使用报告,还能帮助...
总之,MemoryAnalyzer是一款强大的Java内存分析工具,对于优化Java应用程序性能,防止内存泄漏,提高系统稳定性具有重要意义。掌握其使用方法,能帮助开发者提升专业技能,更好地驾驭Java内存管理。
MemoryAnalyzer,即MAT(Memory Analyzer Tool),是一款由Eclipse基金会开发的强大的Java内存分析工具,尤其适用于IBM JVM(openj9)上的heap dump文件分析。本文将详细介绍MemoryAnalyzer的特性和功能,以及如何...
MemoryAnalyzer,简称MAT,是IBM公司开发的一款强大的Java内存分析工具,尤其在处理Android应用的内存泄漏问题时,MAT显得尤为关键。本文将深入探讨MAT的功能、使用方法以及如何通过它来定位和解决Android应用中的...
为了帮助开发者更好地理解和优化Java应用程序的内存使用,Eclipse提供了Memory Analyzer Tool(MAT),一个强大的内存分析工具。本文将详细介绍MAT在Windows 64位系统中的使用,以及如何利用MAT对dump文件进行分析。...
Eclipse Memory Analyzer 是一个功能丰富且轻量的 Java 堆内存分析工具,可以用来辅助发现内存泄漏减 少内存占用。 使用 Memory Analyzer 来分析生产环境的 Java 堆转储文件,可以从数以百万计的对象中快速计算出对 ...
内存分析是Java应用程序性能优化的关键环节,而Memory Analyzer Tool (MAT) 是IBM提供的一款强大的、独立的内存分析工具,它并非作为Eclipse的集成插件存在。MAT的强大之处在于其能够帮助开发者深入理解应用程序的...
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存...
Eclipse Memory Analyzer(MAT,全称Memory Analyzer Tool)是一款强大的Java内存分析工具,尤其在Mac平台上,它提供了独立于Eclipse环境的版本,方便开发者直接使用。MAT的主要目标是帮助开发者诊断和解决Java应用...
标题中的"MemoryAnalyzer-1.10.0_x86_64.zip"指的是MAT的一个特定版本,即1.10.0,针对64位架构设计。这个版本包含了对64位JVM的优化,使得它能有效地分析那些运行在64位操作系统上的Java应用的内存使用情况。 描述...
MAT(Memory Analyzer Tool)工具是eclipse的一个插件,使用起来非常方便,尤其是在分析大内存的dump文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用OQL对象查询,...
Eclipse Memory Analyzer(内存分析器)是一款专门为Java堆内存分析而设计的工具,它可以协助开发者快速地分析内存泄漏问题,通过生成的报告指出潜在的内存泄漏可疑点。Memory Analyzer可以单独使用,也可以作为...