Java中软引用和强引用

在深入理解Java虚拟机这本书中又这么一段话`只被软引用关联着的对象,在系统将要发生内 存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存, 才会抛出内存溢出异常。`

但是在我动手做实验的时候发现了一个问题,那就是在idea中使用Java8的环境,还是会爆出溢出,但是在Java11中却不会。

 

import java.lang.ref.SoftReference;

public class references {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());
        byte[] m2 = new byte[1024 * 1024 * 15];
        System.out.println(m.get());
    }
}

 

这个问题可能与Java 8和Java 11的垃圾回收机制有关。在Java 8中,垃圾回收器使用的是Parallel Scavenge收集器,它的特点是在进行垃圾回收时会尽可能地利用所有可用的CPU资源,以达到更高的吞吐量。但是,这种垃圾回收器对于软引用对象的处理可能不够及时,导致在内存不足时仍然会抛出内存溢出异常。
而在Java 11中,垃圾回收器使用的是G1收集器,它的特点是将堆内存分成多个区域,每个区域独立进行垃圾回收,可以更加精细地控制内存的使用。同时,G1收集器对于软引用对象的处理也更加及时,可以更快地将这些对象列入回收范围,避免内存溢出异常的发生。
因此,建议在使用软引用对象时,尽可能使用较新版本的Java虚拟机,以获得更好的垃圾回收效果。同时,也需要注意软引用对象的使用场景,避免出现内存泄漏等问题。