【发布时间】:2014-06-08 08:24:36
【问题描述】:
据我所知,当我们创建 ArrayList 时:
ArrayList<String> list = new ArrayList<String>(SIZE);
JVM 为其预留a contiguous part of memory。当我们向列表中添加新元素时,当元素数量达到SIZE 的 75% 时,它会保留一个新的、连续的内存部分并复制所有元素。
我们的名单越来越大。我们正在添加新对象,并且必须再次重建列表。
现在会发生什么?
JVM 正在寻找一段连续的内存,但没有找到足够的空间。
垃圾收集器可以尝试删除一些未使用的引用并对内存进行碎片整理。如果 JVM 在此过程之后无法为新的列表实例保留空间,会发生什么情况?
它是否创建一个新的,使用最大可能的段?哪个Exception会被抛出?
我读了这个问题Java: How ArrayList manages memory,答案之一是:
Reference doesn't consume much space. 但无论如何,都会占用一些空间。当数组变大时,这可能是一个问题。我们也不能忘记,我们还有其他使用内存空间的东西。
【问题讨论】:
-
ArrayList在 75% 满时实际上不会调整大小;它会一直等到它完全装满,然后您尝试添加另一个元素。 -
感谢您的评论。我检查了
ArrayList的实现。我从方法add(E e)开始,我无法理解一种情况。在方法ensureCapacityInternal(int minCapacity)中有这样的东西:if (minCapacity - elementData.length > 0) {grow(minCapacity);}。它说什么?在这种情况下,minCapacity是什么意思?方法grows做Arrays.copyOf(elementData, newCapacity)很清楚,但是为什么会有我之前提到的条件呢? -
如果您查看例如
addAll(Collection c)方法,您会看到它调用了ensureCapacity(size() + c.size())。所以minCapacity是容纳我想要放入列表中的内容所需的最小容量。 -
@GirlyGirl Q1 - 哈希表实现通常使用素数作为表大小。 Q2 - 您不希望 HashMap 100% 满,因为这会降低访问项目的速度。
-
@GirlyGirl (smaller load factor, less collisions)