内存分配信息
class A{}
A a = new A(); new的时候就会在堆里申请个空间,具体空间多大决定A类里的东西多少 (申请空间是由程序员完成,释放是由虚拟机自动完成)
GC 垃圾回收
perm:永久 主要存放JAVA类 常量等信息
old:老年区 old扫描是对整个堆的扫描 时间很长 full gc
eden:新生代
对象创建先进入新生代 然后回收一次 进入s0 s1 ,如果还不被回收再进入老年区(回收好几次没被释放的对象)
线程栈 --与CPU相关 分析的线程 stack
线程栈dump --快照
堆内存 -- 与内存相关 分析的对象 heap
堆内存dump --快照
下图:eplisce里设置堆xms初始大小 xmx最大 -verbose:gc 堆信息输出
内存溢出代码示例
static HashMap map; //全局
public static void main(String[] args){
test1();
test2();
}
public static void test1(){//有两个对象引用a 一个A 由于作用域原因 是个局部变量 所以test1方法完成 会释放 put里传入的引用a 由于map是全局变量,所以得等teste2也跑完才会释放
map = new HashMap();
A a = new A();
map.put(a);
public static void test2(){
死循环、处理时间过长 就导致put里传入的a引用不能及时释放
}
分析内存泄露流程 出现现象cpu过高->fullgc频繁->频繁垃圾回收导致
1、通过fullgc的频率 来分析是否有可能内存泄露
fullgc原因 堆内存设置大小、物理内存大小、内存泄露导致
2、定位内存泄露 监控对象的使用情况 可以通过jvm jprofiler 堆内存做dump
内存泄漏常发生于如下场景:
• 全局的容器类(如HashMap,或者自定义的容器类等),在对象不再需要时,忘记从容器
中remove,这样这个对象就会仍然被HashMap等引用到,造成这个对象不满足垃圾回收的
条件,从而造成内存泄漏。特别地,在抛出异常的时候,一定要确保remove被执行到。详
见第§5.1节第102页介绍的幽灵代码。
• 像Runnable对象等被java虚拟机自身管理的对象,没有正确的释放渠道。runnable对象必
须交给一个Thread去run,否则该对象就永远不会消亡。因为像这种对象,尽管不被应用程
序中的其它用户对象访问,但是这种对象会被虚拟机内部所引用。