java – 在完整的GC期间是否清除了WeakHashMap?

WeakHashMap遇到一些麻烦.

考虑这个示例代码

List<byte[]> list = new ArrayList<byte[]>();

Map<String,Calendar> map = new WeakHashMap<String,Calendar>();
String anObject = new String("string 1");
String anOtherObject = new String("string 2");

map.put(anObject,Calendar.getInstance());
map.put(anOtherObject,Calendar.getInstance());
// In order to test if the weakHashMap works,i remove the StrongReference in this object
anObject = null;
int i = 0;
while (map.size() == 2) {
   byte[] tab = new byte[10000];
   System.out.println("iteration " + i++ + "map size :" + map.size());
   list.add(tab);
}
System.out.println("Map size " + map.size());

代码工作.在循环中,我正在创建对象.当发生次要的GC时,地图大小在第1360次迭代时等于1.一切都OK.

现在我评论这一行:

//anObject = null;

我期望有一个OutOfMemoryError,因为mapSize总是等于2.但是在26XXX的迭代中,一个完整的GC发生,地图大小等于0.我不明白为什么?

我认为地图不应该被清除,因为还有很强的引用对象.

解决方法

即时编译器分析代码,看到在循环之后没有使用anObject和anOtherObject,并将它们从本地变量表中删除或将其设置为null,同时循环仍在运行.这被称为OSR编译.

之后,GC收集字符串,因为没有强烈的引用.

如果在循环后使用anObject,你仍然会得到一个OutOfMemoryError.

更新:您将在我的博客中找到关于OSR compilation的更详细的讨论.

相关文章

ArrayList简介:ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增...
一、进程与线程 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程...
本文为博客园作者所写:&#160;一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 简单的一个类...
#############java面向对象详解#############1、面向对象基本概念2、类与对象3、类和对象的定义格式4、...
一、什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域...
Collection接口 Collection接口 Collection接口 Collection是最基本的集合接口,一个Collection代表一组...