gpt4 book ai didi

java - java中100万个引用集合的内存分配

转载 作者:行者123 更新时间:2023-12-02 09:23:15 25 4
gpt4 key购买 nike

我创建了一个包含 100 万个 MyItem 对象的 ArrayList,消耗的内存为 106mb(从任务管理器检查)但是通过 addAll() 方法将相同的列表添加到另外两个列表后,需要 259mb。我的问题是我只添加了对 list 的引用,在 100 万个之后没有创建新对象。为什么即使使用 LinkedList 内存消耗也会增加(因为它不需要连续的内存块,因此不会进行重新分配)?

如何有效地实现这一目标?数据在我的程序中经过各种列表,消耗了超过 1GB 的内存。上面介绍了类似的场景。

public class MyItem{
private String s;
private int id;
private String search;

public MyItem(String s, int id) {
this.s = s;
this.id = id;
}

public String getS() {
return s;
}

public int getId() {
return id;
}


public String getSearchParameter() {
return search;
}

public void setSearchParameter(String s) {
search = s;
}
}

public class Main{
public static void main(String args[]) {
List<MyItem> l = new ArrayList<>();
List<MyItem> list = new LinkedList<>();
List<MyItem> list1 = new LinkedList<>();

for (int i = 0; i < 1000000 ; i++) {
MyItem m = new MyItem("hello "+i ,i+1);
m.setSearchParameter(m.getS());
l.add(i,m);
}

list.addAll(l);

list1.addAll(l);
list1.addAll(list);

Scanner s = new Scanner(System.in);
s.next();//just not to terminate
}
}

最佳答案

LinkedListdoubly-linked list ,因此列表中的元素由节点表示,每个节点包含3个引用。

从 Java 8 开始:

private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

由于您使用大量内存,因此您可能没有使用压缩的 OOP,因此引用可能是 64 位,即每个引用 8 个字节。

对象头为 16 字节 + 每个引用 8 字节,一个节点占用 40 字节。如果有 100 万个元素,则大小为 40 Mb。

两个列表是 80 Mb,然后记住 Java 内存被分割成池,并且对象(节点)会四处移动,现在额外消耗 153 Mb 的内存似乎是正确的。

注意:Arraylist 每个元素仅使用 8 个字节,而不是 40 个字节,如果您预先分配后备数组(因为您知道大小,所以可以这样做),您将节省大量资源内存就是这样。

关于java - java中100万个引用集合的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37227801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com