以最少的内存消耗重新使用 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 个列表,故事结束。
我在 Java 中有一个 List
因此,在填充列表时,我使用了以下逻辑。
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 个列表,故事结束。