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
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”(包括空格和数字)