以最少的内存消耗重新使用 ArrayList

Resuse ArrayList with least memory consumption

我在 Java 中有一个 List> 对象。内部 ArrayList 大小不变。

因此,在填充列表时,我使用了以下逻辑。

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
for(i = 0; i < 10; i++) {
    ....
    for(j = 0; j < 10; j++) {
        list.add(/* some string */);
    }
    map.add(list);
    list.clear();
}

地图中的每个列表都填充了空值。 或者,在每个循环中单独实例化列表,解决了我的问题,例如:

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
for(i = 0; i < 10; i++) {
    ....
    list = new ArrayList<String>();
    for(j = 0; j < 10; j++) {
        list.add(/* some string */);
    }
    map.add(list);
    //list.clear();
}

我有一个大约100,000个ArrayLists的数据集需要存储在List对象中,我不想每次都实例化ArrayList,因为内存开销。

所以,我没有单独实例化它,而是尝试了另一种方法:

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
for(i = 0; i < 10; i++) {
    ....
    for(j = 0; j < 10; j++) {
        list.add(/* some string */);
    }
    map.add(new ArrayList<String>(list));
    list.clear();
}

这些方法中哪一个会给我最少的内存消耗(性能不是优先考虑的)? 如果不是这些,是否有其他方法可以更有效地完成此操作?

都没有。两者都有。 Java 是一种垃圾收集语言。 JVM的配置对内存消耗有严格的上限。

不要忘记将指向对象的指针存储在列表中。不是对象本身。

ArrayList<String> list = new ArrayList<String>();
for(i = 0; i < 10; i++) {
    ....
    for(j = 0; j < 10; j++) {
        list.add(/* some string */);
    }
    map.add(list);
    list.clear();
}

您将列表存储在 map 对象中,然后删除列表中的所有内容。 map 中的列表不是您列表的副本!最后,地图将包含 10 倍相同的空列表。

在 java 中,数组列表大小将是一个指针(64 位)+ 'arraysize' 内容指针 + 一些字节的内容。 'Arraysize' 不是内容大小。 为了减少消耗,您可以将 arraysize 设置为内容大小。

List<ArrayList<String>> map = new ArrayList<ArrayList<String>>(10);
for(i = 0; i < 10; i++) {
    ....
    ArrayList<String> list = new ArrayList<String>(10);
    for(j = 0; j < 10; j++) {
        list.add(/* some string */);
    }
    map.add(list);
}

无论如何,与内容大小相比,列表大小通常是微不足道的。

如果您关心内存消耗,最好的办法是在完成列表填充后调用 trimToSize()。这会删除其中的空容量(如果添加元素,则需要调整大小)。

你仍然需要使用不同的列表,所以第二种方法是任何理智的程序员都会做的。

I don't want to instantiate the ArrayList each time, because of the memory overhead.

没有内存开销。您正在使用内存,因为您需要这样做。如果您想拥有约 100,000 个列表,则必须创建约 100,000 个列表,故事结束。