与 Vector 相比,使用 ArrayList 是否占用更少的内存?我已经读过当向量达到最大大小时,Vector 将其内部数组大小加倍,而 ArrayList 只将它的大小减半?这是一个真实的说法吗?当我没有用 initialcapacity 和 capacityIncrement 的值声明 Vector 时,我需要答案。
3 回答
是的,就内部数组的内存分配而言,您是正确的:
在内部,ArrayList 和 Vector 都使用 Array 保存它们的内容。将元素插入 ArrayList 或 Vector 时,如果对象空间不足,则需要扩展其内部数组。Vector 默认将其数组大小增加一倍,而 ArrayList 将其数组大小增加 50%。
更正
这些 Vector 并不总是会使容量翻倍。它可能只是将其大小增加到构造函数中提到的增量:
public Vector(int initialCapacity, int capacityIncrement)
grow方法中的逻辑是如果没有提到increment,则将容量增加一倍,否则使用capabilityIncrement,这里是Vector grow方法的代码:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
两者之间没有可比性Vector
,ArrayList
因为它们适合不同的目的。Vector
应该是一个并发安全的List
实现。但是,该类的设计存在严重缺陷,并且没有为最常见的迭代用例提供并发保证。
Vector
本身很容易被Collections.synchronizedList (new ArrayList()) 替换。结果当然包含与Vector
. Vector
应视为已弃用。
现在,使用Vector
是理解 Java 和并发编程的天真标志。不要使用它。
回答最初的问题:
ArrayList
默认情况下,容量会增加当前容量的一半。但是,在任何时候,程序都可以调用ensureCapacity
将容量设置为适当的大值。
Vector
默认情况下,容量会增加一倍。但是,有一个构造函数允许设置增长量。使用较小的增长值将对性能产生负面影响。此外,您实际上可以获得更少的容量,因为每次增长都需要一个重复的数组在内存中存在很短的时间。
OP 在评论中表示:
应用程序提取了巨大的数据集,由于堆大小最大化,我们目前面临内存不足
首先,如果程序试图将容量增加到超过设定的限制,Vector
两者ArrayList
都会抛出一个。OutOfMemoryError
您需要确保 OOME 不是源自类的hugeCapacity
方法Vector
。如果是这种情况,那么也许您可以尝试LinkedList
.
其次,您当前的堆大小是多少?默认的 JVM 堆大小相当小。目的是避免完全 GC 的暂停或断断续续的行为对 applet 的用户来说变得明显。然而,对于一个相当复杂的应用程序或一个相当愚蠢的服务来说,堆大小通常也太小了。JVM 参数可-Xmx
用于增加堆大小。