Java 什么时候';参考对象';可以回收吗?

Java 什么时候';参考对象';可以回收吗?,java,jvm,heap,Java,Jvm,Heap,现在,我遇到了这样一个奇怪的情况: public class SoftRefDemo { private static List<SoftReference<String>> cache; public static void main(String[] args) { int total = 3000000; cache = new ArrayList<SoftReference<String>

现在,我遇到了这样一个奇怪的情况:

public class SoftRefDemo {

     private static List<SoftReference<String>> cache;

     public static void main(String[] args) {
         int total = 3000000;
         cache = new ArrayList<SoftReference<String>>(total);
         for (int i = 0; i < total; i++) {
             cache.add(new SoftReference<String>("fafsfsfsdf" + i));
         }

         System.out.println(cache.size());
     }

}
公共类SoftRefDemo{
私有静态列表缓存;
公共静态void main(字符串[]args){
国际贸易总额=3000000;
缓存=新的阵列列表(总计);
对于(int i=0;i
我已经设置了JVM设置:-Xms20m-Xmx40m。当我想将许多SoftReference放到缓存中时,JVM会在没有任何提示或异常的情况下退出。实际上,我怀疑SoftReference的作用,它是JVM的特殊对象。有人能解释一下这个节目发生了什么吗

另外两个问题: 1.JVM堆中的“特殊引用实例”是否有额外的内存分配方法?
2.当引用实例指针指向的实例被释放时,这些引用实例何时可以被释放?非常感谢

如果我使用
-mx40m

char[] chars = new char[4096];
List<SoftReference<String>> strings = new ArrayList<SoftReference<String>>();
do {
  strings.add(new SoftReference<String>(new String(chars)));
} while(strings.get(0).get()!=null);
int nulls=0, set=0;
for (SoftReference<String> string : strings) {
  if(string.get() == null) nulls++; else set++;
}
System.out.println("nulls= "+nulls+", was still set= "+set);
weakreference和softreference的一个问题是,它们往往会同时被清除


试试WeakReference,软引用只有在必要时才是清晰的。为了更清楚地看到它们,请尝试创建一个足够大的数组来触发OutOfMemoryError

  • 所有对象都在堆中。甚至静态字段也包装在堆上的伪对象中。(后一种行为没有定义,但我认为它是如何工作的)

  • 引用实例被丢弃后将被释放(与任何其他对象一样)


  • 如果我使用
    -mx40m

    char[] chars = new char[4096];
    List<SoftReference<String>> strings = new ArrayList<SoftReference<String>>();
    do {
      strings.add(new SoftReference<String>(new String(chars)));
    } while(strings.get(0).get()!=null);
    int nulls=0, set=0;
    for (SoftReference<String> string : strings) {
      if(string.get() == null) nulls++; else set++;
    }
    System.out.println("nulls= "+nulls+", was still set= "+set);
    
    weakreference和softreference的一个问题是,它们往往会同时被清除


    试试WeakReference,软引用只有在必要时才是清晰的。为了更清楚地看到它们,请尝试创建一个足够大的数组来触发OutOfMemoryError

  • 所有对象都在堆中。甚至静态字段也包装在堆上的伪对象中。(后一种行为没有定义,但我认为它是如何工作的)

  • 引用实例被丢弃后将被释放(与任何其他对象一样)

  • 当OOM发生时,总是有很多SoftReference实例已经存在,您能帮我解释一下这种情况吗

    SoftReference的每个实例本身占用24字节的堆内存(对于32位Sun JVM是如此,对于其他VM可能有所不同)。您正试图在列表中存储3'000'000个实例,这意味着您将需要至少~70Mb的堆空间来存储
    SoftReference
    对象

    SoftReference
    对象保留对软可访问对象(在您的情况下为字符串)的“软引用”,JVM规范保证在虚拟机抛出
    OutOfMemoryError
    之前,这些引用将被清除(即字符串对象将被垃圾收集)。但是,JVM不会垃圾收集SoftReference对象,因为您从
    缓存
    列表中保留对它们的强引用。(因此,如果需要从堆中删除SoftReference对象,请将其从
    缓存
    列表中删除)

    当OOM发生时,总是有很多SoftReference实例已经存在,您能帮我解释一下这种情况吗

    SoftReference的每个实例本身占用24字节的堆内存(对于32位Sun JVM是如此,对于其他VM可能有所不同)。您正试图在列表中存储3'000'000个实例,这意味着您将需要至少~70Mb的堆空间来存储
    SoftReference
    对象


    SoftReference
    对象保留对软可访问对象(在您的情况下为字符串)的“软引用”,JVM规范保证在虚拟机抛出
    OutOfMemoryError
    之前,这些引用将被清除(即字符串对象将被垃圾收集)。但是,JVM不会垃圾收集SoftReference对象,因为您从
    缓存
    列表中保留对它们的强引用。(因此,如果需要从堆中删除SoftReference对象,请将其从
    缓存列表中删除)。

    请不要关闭。我认为用户有一些真正的问题,这是一个语言问题,导致缺乏清晰度@Denny,请尝试重新表述问题,您的问题无法理解,因为目前StateI已将“总计”值从10000设置为10000000,并查看执行情况。当缓存有少量字符串实例时,它会正常运行,并在JVM退出前打印结果。此外,创建了越来越多的实例,JVM执行程序需要很长时间,并且会毫无例外地退出,结果是“System.out.println(cache.size())”。在我看来,JVM没有到达最后一个字节码。我为这个程序创建了堆转储文件。原因是“OOM”,而使用最多的实例是“SoftReference”(包括空格和数字)。如果JVM退出时没有打印“OOM”异常堆栈跟踪,对我来说这看起来像是一个bug。OOM(实例编号)java.lang.ref.SoftReference 887848 java.lang.String 1321内存泄漏请不要关闭。我认为用户有一些真正的问题,这是一个语言问题,导致缺乏清晰度@Denny,请尝试重新表述问题,您的问题无法理解,因为目前StateI已将“总计”值从10000设置为10000000,并查看执行情况。当缓存有少量字符串实例时,它会正常运行,并在JVM退出前打印结果。此外,创建了越来越多的实例,JVM执行程序需要很长时间,并且会毫无例外地退出,结果是“System.out.println(cache.size())”。在我看来,JVM没有到达最后一个字节码。我为这个程序创建了堆转储文件。原因是“OOM”,而使用最多的实例是“SoftReference”(包括空格和数字)