最近刷题学数据结构,研究ArrayList时因为仿写的ArrayList实现手段与JDK不同(clear方法),测试结果与预期的有偏差(我仿写的效果居然更好),请教有经验的猿们具体啥情况。(是我测试有错,还是我结果看的不对,又或者是别的情况)
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;
}
最大的差异就是我没有for循环遍历逐个清空。
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/archives/Java-%E5%AF%B9%E8%B1%A1%E4%B8%8D%E5%86%8D%E4%BD%BF%E7%94%A8%E6%97%B6%E8%B5%8B%E5%80%BC%E4%B8%BAnull%E7%9A%84%E4%BD%9C%E7%94%A8%E5%92%8C%E5%8E%9F%E7%90%86.html
再加上JDK的写法,针对gc机制,都是设置null触发。为什么我的方案直接设置为空,等价于new一个新的对象,不管之前内容的占用会清理的更好?是我理解有误还是JDK做了别的优化?
配置的vmoption:-verbose:gc
项目完整内容在github上:
https://github.com/wyue1227/DataStructuresAndAlgorithms/blob/main/src/com/yue/season1/class02/Main.java
你这个写法应该有点问题,当调用了clear 方法后,不能再做添加元素的操作了。
你有算过总时间吗?我觉得不管怎样都是差不多的。
你只是把当前变量指向了一个为空的内存地址把,那JVM怎么知道原来的List的内存地址是否需要GC?那么是否会占用内存,你可以看看具体处理完后,不手动GC的内存消耗
只是我的观点,具体没论证