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的详细信息:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |