美文网首页java-DumpJava 杂谈
java虚拟机内存溢出和泄漏实例

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

作者: 远方的梦Java | 来源:发表于2018-06-21 16:42 被阅读46次

    测试参数设置:

    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 : 是清理整个堆空间—包括年轻代和老年代

    相关文章

      网友评论

        本文标题:java虚拟机内存溢出和泄漏实例

        本文链接:https://www.haomeiwen.com/subject/dghcyftx.html