美文网首页
java虚拟机(3)-引用

java虚拟机(3)-引用

作者: 懒癌晚期的自律 | 来源:发表于2019-12-28 17:51 被阅读0次

    判断对象的存活

    引用计数法:快,方便,实现简单;缺点:对象相互应用,很难判断对象是否回收

    可达性分析

    判断对象是否存活的。这个算法的基本思路是通过系列的称为“GC Roots”的对象作为起始点,从这些几点开始向下搜索,搜索所走过的路径称为引用链接(reference Chain),当一个对象GC roots没有任何应用链相连是,则证明此对象是不可用的。

    作为GC Roots的对象包括下面几种:

    • 虚拟机栈(栈帧中的本地变量表)中引用对象。
    • 方法区中的类静态属性引用的对象。
    • 方法区中常量引用对象。
    • 本地方法栈中JNI(即一般说的Native方法)引用的对象
    image.png

    引用

    强引用

    • 一般的Object obj = new Object(); 就属于强引用

    软引用 SoftReference

    • 一些有用但是并非必需,用软引用关联的对象,系统将要发生OMM(内存溢出)之前,这些对象就会被回收。
    public static class User{
            
            public int id = 0;
            public String name = "";    
            
            public User(int id,String name) {
                this.id = id;
                this.name=name;
            }
        
        }
        
    
    
        public static void main(String[] args) {
            
            User user = new User(1, "小明");
            SoftReference<User> userSoft = new SoftReference<User>(user);
            user = null;
            
            System.out.println(userSoft.get());
            System.gc();
            System.out.println("GC完成后");
            System.out.println(userSoft.get());
            
            List<Byte[]> list = new  LinkedList<Byte[]>();
            
            try {
                for (int i = 0; i < 10000; i++) {
                System.out.println("**********"+userSoft.get());
                list.add(new Byte[1024*1024*1]);
                }
                
            } catch (Throwable e) {
                System.out.println("Throwable***********"+userSoft.get());
            }
            
            
        }
    

    运行结果:

    [GC (System.gc())  893K->632K(9728K), 0.0013160 secs]
    [Full GC (System.gc())  632K->569K(9728K), 0.0054084 secs]
    GC完成后
    com.enjoy.cap1.StackAlloc$User@7852e922
    **********com.enjoy.cap1.StackAlloc$User@7852e922
    **********com.enjoy.cap1.StackAlloc$User@7852e922
    [GC (Allocation Failure)  4670K->4825K(9728K), 0.0002478 secs]
    [GC (Allocation Failure)  4825K->4761K(9728K), 0.0003084 secs]
    [Full GC (Allocation Failure)  4761K->4665K(9728K), 0.0064745 secs]
    [GC (Allocation Failure)  4665K->4665K(9728K), 0.0004925 secs]
    [Full GC (Allocation Failure)  4665K->4652K(9728K), 0.0067316 secs]
    Throwable***********null
    
    

    弱引用 WeakReference

    一些有用(程度比软引用更低)但是并非必需,用弱引用相关的对象,只能生存到下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收

    public static class User{
            
            public int id = 0;
            public String name = "";    
            
            public User(int id,String name) {
                this.id = id;
                this.name=name;
            }
        
        }
        
    
    
        public static void main(String[] args) {
            
            User user = new User(1, "小明");
            WeakReference<User> userSoft = new WeakReference<User>(user);
            user = null;
            
            System.out.println(userSoft.get());
            System.gc();
            System.out.println("GC完成后");
            System.out.println(userSoft.get());
            
        }
    

    运行结果:

    [GC (System.gc())  892K->600K(9728K), 0.0006343 secs]
    [Full GC (System.gc())  600K->569K(9728K), 0.0039438 secs]
    GC完成后
    null
    
    

    虚应用 PhantomReference

    幽灵引用,最弱,被垃圾会后的时候收到一个通知

    \color{red}{注意}: 软引用SoftReference和弱引用WeakReference,可以用在内存资源紧张的情况下以及创建不是很重的数据缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。 例如:一个程序用来处理用户提供的图片。如果将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些使用较少的图片浪费内存空,需要手动冲内存中移除,如果每次打开图片都是从磁盘文件中读取到内存中再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都要访问磁盘,代价巨大。这个是偶就是可以用软引用构建对象

    相关文章

      网友评论

          本文标题:java虚拟机(3)-引用

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