• 关于SoftReference的使用


    SoftReference一般可以用来创建缓存的,缓存我们经常使用,例如:我们在浏览器中浏览了一个网页后,点击跳转到新的网页,我们想回去看之前的网页,一般是点击回退按钮,那么这个时候之前的网页一般就是放在缓存中了。如果网页太多,有时候就会造成回不去的情形,这说明如果内存不够用了,就删除了这些缓存。

    类似这种情形就可以用SoftReference来实现,SoftReference的GC机制是这样的,如果内存够用,它不会被GC,但如果内存不够用,且内存中的对象只被一个SoftRerence类型的引用指向的话(一个对象也可以被一个强引用和软引用同时指向),那么它就会被GC。

    那么这个时候有一个疑问,如果用SoftReference引用指向的对象内部有强引用指向的复杂对象,那么当内存不足时的会如何处理呢?

    看下面代码:

     1 import java.lang.ref.*;
     2 
     3 public class Test {
     4 
     5     static final int MB = 1024 * 1024;
     6 
     7     byte[] b = new byte[4 * MB];
     8 
     9     public static void main(String[] args) {
    10 
    11         SoftReference<Test> test = new SoftReference<Test>(new Test());
    12         // Test test = new Test();
    13         byte[] c = new byte[4 * MB];
    14     }
    15 }

    我们调整运行参数:

    则个运行结果是:

     1 [GC [PSYoungGen: 313K->288K(2368K)] 4409K->4384K(7872K), 0.0006568 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
     2 [GC [PSYoungGen: 288K->288K(2368K)] 4384K->4384K(7872K), 0.0002187 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
     3 [Full GC [PSYoungGen: 288K->0K(2368K)] [PSOldGen: 4096K->4293K(5504K)] 4384K->4293K(7872K) [PSPermGen: 2952K->2952K(21248K)], 0.0029254 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
     4 [GC [PSYoungGen: 0K->0K(2368K)] 4293K->4293K(7872K), 0.0000939 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
     5 [Full GC [PSYoungGen: 0K->0K(2368K)] [PSOldGen: 4293K->192K(4544K)] 4293K->192K(6912K) [PSPermGen: 2952K->2949K(21248K)], 0.0033466 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
     6 Heap
     7  PSYoungGen      total 2368K, used 41K [0x000000000aed0000, 0x000000000b170000, 0x000000000b170000)
     8   eden space 2048K, 2% used [0x000000000aed0000,0x000000000aeda478,0x000000000b0d0000)
     9   from space 320K, 0% used [0x000000000b0d0000,0x000000000b0d0000,0x000000000b120000)
    10   to   space 320K, 0% used [0x000000000b120000,0x000000000b120000,0x000000000b170000)
    11  PSOldGen        total 4544K, used 4288K [0x000000000a970000, 0x000000000ade0000, 0x000000000aed0000)
    12   object space 4544K, 94% used [0x000000000a970000,0x000000000ada00c8,0x000000000ade0000)
    13  PSPermGen       total 21248K, used 2989K [0x0000000005570000, 0x0000000006a30000, 0x000000000a970000)
    14   object space 21248K, 14% used [0x0000000005570000,0x000000000585b6f8,0x0000000006a30000)

    虚拟机堆区大小被限制在7MB,然后分配了一个含有4MB的SoftReference类,然后当继续申请4MB堆区时,JVM就会回收掉test所指向的对象。

    如果按下面这样去写代码,就会报出OutOfMemoryError。

    import java.lang.ref.*;
    
    public class Test {
    
        static final int MB = 1024 * 1024;
    
        byte[] b = new byte[4 * MB];
    
        public static void main(String[] args) {
    
            //SoftReference<Test> test = new SoftReference<Test>(new Test());
            Test test = new Test();
            byte[] c = new byte[4 * MB];
        }
    }

    内纯回收日志:

    [GC [PSYoungGen: 313K->272K(2368K)] 4409K->4368K(7872K), 0.0006490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    [GC [PSYoungGen: 272K->288K(2368K)] 4368K->4392K(7872K), 0.0001820 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    [Full GC [PSYoungGen: 288K->0K(2368K)] [PSOldGen: 4104K->4296K(5504K)] 4392K->4296K(7872K) [PSPermGen: 2952K->2952K(21248K)], 0.0028587 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    [GC [PSYoungGen: 0K->0K(2368K)] 4296K->4296K(7872K), 0.0001105 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    [Full GC [PSYoungGen: 0K->0K(2368K)] [PSOldGen: 4296K->4288K(5504K)] 4296K->4288K(7872K) [PSPermGen: 2952K->2948K(21248K)], 0.0036936 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at Test.main(Test.java:13)
    Heap
     PSYoungGen      total 2368K, used 82K [0x000000000af70000, 0x000000000b210000, 0x000000000b210000)
      eden space 2048K, 4% used [0x000000000af70000,0x000000000af84868,0x000000000b170000)
      from space 320K, 0% used [0x000000000b170000,0x000000000b170000,0x000000000b1c0000)
      to   space 320K, 0% used [0x000000000b1c0000,0x000000000b1c0000,0x000000000b210000)
     PSOldGen        total 5504K, used 4288K [0x000000000aa10000, 0x000000000af70000, 0x000000000af70000)
      object space 5504K, 77% used [0x000000000aa10000,0x000000000ae400a8,0x000000000af70000)
     PSPermGen       total 21248K, used 2990K [0x0000000005610000, 0x0000000006ad0000, 0x000000000aa10000)
      object space 21248K, 14% used [0x0000000005610000,0x00000000058fbb60,0x0000000006ad0000)
  • 相关阅读:
    快速提取某一文件夹下所有文件名称
    CFileFind类的使用总结
    FILE文件流的中fopen、fread、fseek、fclose的使用
    经典损失函数:交叉熵(附tensorflow)
    tensorboard使用
    Windows下 tensorboard出现ValueError:Invalid format string
    新建全色或者resize(毫无价值,只是做记录)
    创建一个任意大小的全色矩阵 python
    转移图片位置
    getpatch
  • 原文地址:https://www.cnblogs.com/chaiwentao/p/4773247.html
Copyright © 2020-2023  润新知