关于JVM设空值的不解

新手上路,请多包涵

背景

最近刷题学数据结构,研究ArrayList源码时因为仿写的ArrayList实现手段与源码不同(clear方法),测试结果与预期的有偏差(源码的处理效果不好),想请教有经验的猿们具体啥情况。

代码

clear方法

JDK1.8

public void clear() {
    modCount++;
    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    size = 0;
}

仿写

/**
 * 空值
 */
private static final Object[] EMPTY_ELEMENT = {};
public void clear() {
    size = 0;
    elements = EMPTY_ELEMENT;
}

测试方法

clear2()是仿照JDK源码写的方法。

public static void test1() {
    MyArrayList<Integer> myArrayList = new MyArrayList<Integer>(1);
    for (int i = 0; i < 10000000; i ++) {
        myArrayList.add(i);
    }
    myArrayList.clear();
    System.gc();
}

public static void test2() {
    MyArrayList<Integer> myArrayList = new MyArrayList<Integer>(1);
    for (int i = 0; i < 10000000; i ++) {
        myArrayList.add(i);
    }
    myArrayList.clear2();
    System.gc();
}

测试结果

[GC (Allocation Failure)  28672K->18629K(110080K), 0.0730491 secs]
[GC (Allocation Failure)  47301K->37091K(138752K), 0.0912045 secs]
[GC (Allocation Failure)  79231K->79292K(138752K), 0.2543684 secs]
[Full GC (Ergonomics)  79292K->69918K(226304K), 2.4897254 secs]
[GC (Allocation Failure)  158404K->135196K(254464K), 0.3057838 secs]
[Full GC (Ergonomics)  135196K->121269K(348672K), 3.9478386 secs]
[GC (Allocation Failure)  206773K->206862K(377856K), 0.3599932 secs]
[Full GC (Ergonomics)  206862K->175546K(514560K), 6.3232826 secs]
[GC (System.gc())  205257K->203994K(599040K), 0.2672577 secs]
[Full GC (System.gc())  203994K->966K(599040K), 0.0135492 secs]
================================
[GC (Allocation Failure)  122822K->81343K(595968K), 0.2753535 secs]
[GC (Allocation Failure)  178133K->156860K(625664K), 0.6571283 secs]
[GC (System.gc())  236044K->109967K(667648K), 0.1013700 secs]
[Full GC (System.gc())  109967K->47679K(667648K), 0.0593073 secs]

疑问

针对网上的教程帖子,例如下文:

https://www.polarxiong.com/ar...

再加上源码,针对gc机制,都是设置null触发。为什么我的方案直接设置为空,等价于new一个新的对象,会清理的更好?

配置的vmoption:-verbose:gc

阅读 1.4k
1 个回答

clear是把数组内容清空
clear2是把数组直接扔掉
所以内存使用方面clear2更优,但是实际使用还是clear更优,因为clear之后一般是要重新add东西的,而clear2之后的add需要(可能要多次)扩容

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题