欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

接着进行了 图纸加密 第三次full gc

点击: 次  来源:宝鼎软件 时间:2017-08-10

原文出处: 林玲 投稿

强引用 ( Strong Reference )

强引用是利用最普遍的引用。假如一个工具具有强引用,那垃圾接纳器毫不会接纳它。当内存空间不敷,Java虚拟机甘愿抛出OutOfMemoryError错误,使措施异常终止,也不会靠随意接纳具有强引用的工具来办理内存不敷的问题。 ps:强引用其实也就是我们平时A a = new A()这个意思。

强引用特性

  • 强引用可以直接会见方针工具。
  • 强引用所指向的工具在任何时候都不会被系统接纳。
  • 强引用大概导致内存泄漏。
  • Final Reference

  • 当前类是否是finalizer类,留意这里finalizer是由JVM来符号的( 后头简称f类 ),并不是指java.lang.ref.Fianlizer类。可是f类是会被JVM注册到java.lang.ref.Fianlizer类中的。
  • ① 当前类或父类中含有一个参数为空,返回值为void的名为finalize的要领。
    ② 而且该finalize要领必需非空

  • GC 接纳问题
    1. 工具因为Finalizer的引用而酿成了一个姑且的强引用,纵然没有其他的强引用,照旧无法当即被接纳;
    2. 工具至少经验两次GC才气被接纳,因为只有在FinalizerThread执行完了f工具的finalize要领的环境下才有大概被下次GC接纳,而有大概期间已经经验过多次GC了,可是一直还没执行工具的finalize要领;
    3. CPU资源较量稀缺的环境下FinalizerThread线程有大概因为优先级较量低而延迟执行工具的finalize要领;
    4. 因为工具的finalize要领迟迟没有执行,有大概会导致大部门f工具进入到old分代,此时容易激发old分代的GC,甚至Full GC,GC暂停时间明明变长,甚至导致OOM;
    5. 工具的finalize要领被挪用后,这个工具其实还并没有被接纳,固然大概在不久的未来会被接纳。

    详见:JVM源码阐明之FinalReference完全解读 – 你假笨

    软引用 ( Soft Reference )

    是用来描写一些尚有用但并非必需的工具。对付软引用关联着的工具,在系统将要产生内存溢出异常之前,将会把这些工具列进接纳范畴之中举办第二次接纳。假如这次接纳还没有足够的内存,才会抛出内存溢出异常。

    对付软引用关联着的工具,假如内存富裕,则垃圾接纳器不会接纳该工具,假如内存不足了,就会接纳这些工具的内存。在 JDK 1.2 之后,提供了 SoftReference 类来实现软引用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用行列(ReferenceQueue)连系利用,假如软引用所引用的工具被垃圾接纳器接纳,Java虚拟机就会把这个软引用插手到与之关联的引用行列中。

    留意:Java 垃圾接纳器筹备对SoftReference所指向的工具举办接纳时,挪用工具的 finalize() 要领之前,SoftReference工具自身会被插手到这个 ReferenceQueue 工具中,此时可以通过 ReferenceQueue 的 poll() 要领取到它们。

    /**
     * 软引用:对付软引用关联着的工具,在系统将要产生内存溢出异常之前,将会把这些工具列进接纳范畴之中举办第二次接纳( 因为是在第一次接纳后才会发明内存依旧不富裕,才有了这第二次接纳 )。假如这次接纳还没有足够的内存,才会抛出内存溢出异常。
     * 对付软引用关联着的工具,假如内存富裕,则垃圾接纳器不会接纳该工具,假如内存不足了,就会接纳这些工具的内存。
     * 通过debug发明,软引用在pending状态时,referent就已经是null了。
     *
     * 启动参数:-Xmx5m
     *
     */
    public class SoftReferenceDemo {
    
        private static ReferenceQueue<MyObject> queue = new ReferenceQueue<>();
    
        public static void main(String[] args) throws InterruptedException {
            Thread.sleep(3000);
            MyObject object = new MyObject();
            SoftReference<MyObject> softRef = new SoftReference(object, queue);
            new Thread(new CheckRefQueue()).start();
    
            object = null;
            System.gc();
            System.out.println("After GC : Soft Get = " + softRef.get());
            System.out.println("分派大块内存");
    
            /**
             * ====================== 节制台打印 ======================
             * After GC : Soft Get = I am MyObject.
             * 分派大块内存
             * MyObject's finalize called
             * Object for softReference is null
             * After new byte[] : Soft Get = null
             * ====================== 节制台打印 ======================
             *
             * 总共触发了 3 次 full gc。第一次有System.gc();触发;第二次在在分派new byte[5*1024*740]时触发,然后发明内存不足,于是将softRef列入接纳返回,接着举办了第三次full gc。
             */
    //        byte[] b = new byte[5*1024*740];
    
            /**
             * ====================== 节制台打印 ======================
             * After GC : Soft Get = I am MyObject.
             * 分派大块内存
             * Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
             *      at com.bayern.multi_thread.part5.SoftReferenceDemo.main(SoftReferenceDemo.java:21)
             * MyObject's finalize called
             * Object for softReference is null
             * ====================== 节制台打印 ======================
             *
             * 也是触发了 3 次 full gc。第一次有System.gc();触发;第二次在在分派new byte[5*1024*740]时触发,然后发明内存不足,于是将softRef列入接纳返回,接着举办了第三次full gc。当第三次 full gc 后发明内存依旧不足用于分派new byte[5*1024*740],则就抛出了OutOfMemoryError异常。
             */
            byte[] b = new byte[5*1024*790];
    
            System.out.println("After new byte[] : Soft Get = " + softRef.get());
        }
    
        public static class CheckRefQueue implements Runnable {
    
            Reference<MyObject> obj = null;
    
            @Override
            public void run() {
                try {
                    obj = (Reference<MyObject>) queue.remove();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                if (obj != null) {
                    System.out.println("Object for softReference is " + obj.get());
                }
    
            }
        }
    
        public static class MyObject {
    
            @Override
            protected void finalize() throws Throwable {
                System.out.println("MyObject's finalize called");
                super.finalize();
            }
    
            @Override
            public String toString() {
                return "I am MyObject.";
            }
        }
    }

    弱引用 ( Weak Reference )