java-DumpJava 杂谈

java虚拟机内存溢出和泄漏实例

2018-06-21  本文已影响46人  远方的梦Java

测试参数设置:

1、循环调用new A()实现堆溢出,java.lang.OutOfMemoryError: Java heap space,

虚拟机参数:-Xms1M -Xmx1M -XX:+HeapDumpOnOutOfMemoryError,解释:将-Xmx和-Xms设置为一样可以避免堆自动扩展,-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的堆内存转储快照

//while(true){//new A().do2();//}

2、循环调用对象引用的方式实现栈溢出。java.lang.StackOverflowError,

虚拟机参数:-Xss128k,

解释:设置虚拟机栈的大小为128kn

在单线程下,无论栈帧太大还是虚拟机栈容量太小,内存无法分配的时候都会抛出以上错误

voiddo2(){do2();};

3、循环调用String.intern()方法来写入常量池,常量池溢出。java.lang.OutOfMemoryError: PermGen space

while(true)      {          list.add(String.valueOf(i++).intern());      }

虚拟机参数:-XX:PermSize=10M -XX:MaxPermSize=10M,

解释:表示JVM初始分配的永久代的容量和最大容量。(永久区内存不足,1.8后都在堆上。方法区=永久代,PermGen space”,即永久代)

四种引用状态: (类继承extends WeakReference) 

1、强引用:Object obj = new Object(),只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象;

2、软引用:SoftReference, 被软引用关联的对象会在内存不够时被回收 。如果这次回收还没有足够的内存,才会抛出内存溢出异常;SoftReference sr = new SoftReference(bytes);

3、弱引用:WeakReference,被弱引用关联的对象只能生存到下一次垃圾回收之前;

4、虚引用:PhantomReference, 虚引用是用于跟踪对象的回收状态 。

触发GC的时机:

1、当年轻代或者老年代满了,Java虚拟机无法再为新的对象分配内存空间了,那么Java虚拟机就会触发一次GC去回收掉那些已经不会再被使用到的对象

2、System.gc(), Runtime.getRuntime().gc() 方法,通常这样会触发一次的Full GC以及至少一次的Minor GC,不一定就立即回收。

3、在当前服务器空闲或堆中老年代等占用率较大时触发。

回收无引用对象占据的空间,而不是对象本身。

但真正垃 圾回收机制具体在什么时间点开始发生动作这同样是不可预料的(未开源),这和抢占 式的线程在发生作用时 的原理一样。

分代收集算法:

新生代收集器和老年代收集器。 

标记-清除算法 

标记-整理算法

内存溢出和内存泄露的区别:

1、内存溢出:程序在分配内存的时候没有足够大的空间了。

2、内存泄漏:程序在申请内存之后,没有 办法释放掉内存 ,它始终占用着内存,即被分配的对象可达但无用。内存泄露一般都是因为内存中有一块很大的对象,但是无法释放。            会导致内存溢出。

并行与并发:

1、并行:指多条垃圾收集器线程运行;

2、并发:指用户线程和垃圾收集器线程同时工作。

类加载机制:

1、加载(生成java.lang.class对象)、验证、准备、解析、初始化(赋值过程)、使用(Using)和卸载(Unloading)这7个阶段

2、其中验证(字节流包含的信息是否正确,是否符合jvm)、

准备(为类变量即静态变量赋值,赋0)、

解析(将 符号引用 替换为 直接引用 ,class文件转内存)3个部分统称为连接(Linking)

3、加载阶段:获取.class文件的二进制流;

将类信息、静态变量、字节码、常量这些.class文件中的内容放入方法区

在内存中生成一个代表这个.class文件的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

4、初始化阶段做的事就是 调用 client>方法 给static变量赋予用户指定的值以及执行静态代码块。

双亲委派模型:(启动类加载器>扩展类加载器>应用程序类加载器>自定义类加载器)

一个类加载器收到了类加载的请求,把这个请求委派给父类加载器去完成,父类完不成,自己才去完成。

先行发生原则:

Java内存中的有序性仅仅依靠synchronized和volatile来约束是不行,依靠程序调用次序规则判断setter和getter顺序。 

Minor GC : 清理年轻带内存, 无法为一个新的对象分配空间。

Major GC : 是清理老年代,许多 Major GC 是由 Minor GC 触发的

Full GC : 是清理整个堆空间—包括年轻代和老年代

上一篇下一篇

猜你喜欢

热点阅读