ArrayList容量增长中Java 6和Java 7之间的差异
|
我有一个问题,关于如何在
Java中管理ArrayList的容量增长(不是大小,而是容量).
当我们使用默认构造函数初始化ArrayList而不设置容量时,默认情况下容量设置为10. 此时,当我们向列表中添加另一个元素时,Oracle文档说“当元素添加到ArrayList时,其容量会自动增长.除了添加元素具有常量这一事实之外,未指定增长策略的详细信息摊销时间成本.“ 如果我们看看Java内部,容量增长政策已经改变了它的功能.直到Java 6它是: (1) int newCapacity = (oldCapacity * 3)/2 + 1; 从Java 7(和> 7)开始,它是: (2) int newCapacity = oldCapacity + (oldCapacity >> 1); 但这两个数学系列略有不同.从默认值(10)开始,我们有: (1)10,16,25,38,58,88,133,200,301,452 …… (2)10,15,22,33,49,73,109,163,244,366 …… 我认为这对ArrayList的使用没有任何影响,但为什么他们改变了这个功能呢?有任何表现原因吗?他们发现了旧的瑕疵还是虫子? 解决方法
OpenJDK的
source control history显示它在
changeset 2350更改为
Martin Buchholz from Google以修复错误
JDK-6933217: Huge arrays handled poorly in core libraries.
新代码小心避免不必要的整数溢出.即使oldCapacity * 3/2没有,oldCapacity * 3也会溢出.新行oldCapacity(oldCapacity>> 1)不会.如果它确实溢出并且变为负数,则需要额外的代码来将容量设置为Integer.MAX_VALUE(或接近它). /**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size,so this is a win:
elementData = Arrays.copyOf(elementData,newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
bug report的详细信息:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
