java - 为什么java每次生成的hash id集合几乎一样,调用System.gc()后却变多了?

标签 java garbage-collection

我试图收集java生成的对象id,然后对它们进行排序以查看模式:

public class Test{
    public static void main(String[] args){
        java.util.ArrayList<Integer> a=new java.util.ArrayList<Integer>();
        for(int i=0;i<16;i++){
            //String obj3=new String();
            //Object obj2=new Object();
            Object obj=new Object();
            a.add(System.identityHashCode(obj));
        }
        java.util.Collections.sort(a);
        for(Integer i:a){
            System.out.println(i);
        }
    }
}

一开始我觉得object id应该每次都不一样,因为在我的印象中object id应该和object address有关,但是我运行了几次代码之后似乎返回了相同的一组object id:

205238968
242666487
400535505
424201356
447267976
580487944
592598094
657291792
860080307
1040108132
1165259232
1265744841
1586482837
1608535231
1914494719
2053965899

即使有变化,object id 的集合也非常相似:

205238968
242666487
400535505
424201356
447267976
580487944
592598094
657291792
860080307
1040108132
1165259232
1586482837
1608535231
1914494719
2053965899
2127478981

我尝试通过在收集对象 ID 期间创建一些额外的对象来更改程序:

public class Test{
    public static void main(String[] args){
        java.util.ArrayList<Integer> a=new java.util.ArrayList<Integer>();
        for(int i=0;i<16;i++){
            String obj3=new String();
            Object obj2=new Object();
            Object obj=new Object();
            a.add(System.identityHashCode(obj));
        }
        java.util.Collections.sort(a);
        for(Integer i:a){
            System.out.println(i);
        }
    }
}

但仍然得到非常相似(可能相同)的一组结果:

205238968
242666487
400535505
424201356
447267976
580487944
592598094
657291792
860080307
1040108132
1165259232
1265744841
1586482837
1608535231
1914494719
2053965899

但是当我尝试在创建每个对象之前调用 System.gc() 时:

public class Test{
    public static void main(String[] args){
        java.util.ArrayList<Integer> a=new java.util.ArrayList<Integer>();
        for(int i=0;i<16;i++){
            System.gc();
            Object obj=new Object();
            a.add(System.identityHashCode(obj));
        }
        java.util.Collections.sort(a);
        for(Integer i:a){
            System.out.println(i);
        }
    }
}

对象id的集合每次都有更多的变化(但仍然找到了一些与以前相同的值):

242666487
355475160
550670442
582642819
644278293
657291792
764062238
781143987
1165259232
1220081709
1579321858
1697022030
1726858146
1819177159
2065554654
2094048729

为什么会这样?

最佳答案

多次运行相同的程序得到相同的结果并不奇怪。对象分配在很大程度上是确定性的,并且使用相同的 JVM 配置,您应该期望跨运行的身份哈希码非常相似。

每次执行 GC 时,都会收集 Eden 空间并将 Activity 对象转移到其中一个 Survivor 空间(每个 GC 周期使用另一个 Survivor 空间,即上次不活动的空间)。在几个 GC 周期后仍然存在的对象将被永久使用(转移到老年代)。考虑到代码中 GC 循环的频率,这种情况很快就会发生。所有这些都为您的对象的排列带来了更多的复杂性,因此更多的差异再次是一个非常预期的结果(尽管我仍然期望远离随机行为)。

关于java - 为什么java每次生成的hash id集合几乎一样,调用System.gc()后却变多了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31853121/

相关文章:

.net 内存未回收

java - android - java - 带有 ArrayList 的 WeakReferences?

garbage-collection - 在 GC 语言中是否有关于(或更好地使用)RAII 的研究?

garbage-collection - D 编程语言是否使用增量垃圾收集器?

java - 获取jMeter线程已运行的时间

Java为什么销毁对象后finalize方法不工作?

java - 带有注解的 GSON 自定义序列化

compiler-construction - 为什么要收集垃圾?为什么编译器不自动插入 free() 呢?

java - 无法在 Java Servlet 中反序列化 JSON

java - TestNG 类很少,如何通过一个 'click' 运行所有测试?