简体   繁体   English

Java ArrayList,HashSet和HashMap中的内存重新分配问题

[英]memory reallocation issue in Java ArrayList, HashSet and HashMap

Looked some unofficial references, and want to confirm here my understanding is correct. 看了一些非官方的参考文献,并想在这里确认我的理解是正确的。 Suppose we are adding new (unique) elements from time to time, 假设我们不时添加新的(唯一的)元素,

  1. ArrayList<T> will reallocate for memory since its memory needs to be continuous, when memory grow by newly inserted elements exceeds some threshold, reallocation of larger continuous memory space will happen, and existing elements will be moved to such newly allocated larger continuous memory space; ArrayList<T>将重新分配给内存,因为它的内存需要连续,当新插入的元素增加的内存超过某个阈值时,将发生更大的连续内存空间的重新分配,并且现有元素将被移动到这种新分配的更大的连续内存空间中;
  2. HashSet<T> and HashMap<T> has no such issue since memory of them does not require to be continuous? HashSet<T>HashMap<T>没有这样的问题,因为它们的内存不需要连续吗?

BTW, if some good articles on these areas, appreciate for refer as well. 顺便说一句,如果在这些领域有一些不错的文章,也请参考。

regards, Lin 问候,林

If you checkout the sourcecode of add(E e) method in ArrayList<> in Java 8 (jre 1.8.0_71), it calls in for a method called ensureCapacityInternal(int minCapacity) . 如果您在Java 8(jre 1.8.0_71)中的ArrayList<>中签出add(E e)方法的源代码,它将调用一个名为ensureCapacityInternal(int minCapacity) ie this method is called every time you add in an object to the ArrayList. 也就是说,每次将对象添加到ArrayList中时,都会调用此方法。 This inturn calls in a series of methods and finally if the size of your ArrayList is smaller to hold the newly added element, it calls in a method called grow(int minCapacity) . 依次调用一系列方法,最后,如果ArrayList的大小较小以容纳新添加的元素,它将调用一个称为grow(int minCapacity) This method is as shown below: 该方法如下所示:

/**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    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);
    }

This will create a new array with size 1.5 times more than the initial one and copies all the elements from old array to the new one. 这将创建一个新数组,其大小是初始数组的1.5倍,并将所有元素从旧数组复制到新数组。 This proves your point no. 这证明了你的观点。 1. 1。

Coming back to your point no. 回到你的观点。 2, in case of HashMap<K,V> , they are a special type of array that hold key and value pairs. 2,对于HashMap<K,V> ,它们是一种特殊的数组,用于保存键和值对。 This array slots are called buckets . 该阵列插槽称为buckets So, every object that you add into an HashMap, should override hashCode() and equals() method properly. 因此,添加到HashMap中的每个对象都应正确覆盖hashCode()equals()方法。 When you call put(K key, V value) method, it inturn calls a method called putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) by calculating the #hash of the key hash(Object key) that you have passed. 当您调用put(K key, V value)方法时,它会通过计算键hash(Object key)的#hash依次调用一个名为putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)的方法。你已经过去了。 This hash indicates the bucket location where the Value object shoud go. 此哈希值指示值对象应存储在的存储桶位置。 Hence, the array here only indicates the address blocks where the objects goes in. This thread explains it in more detail. 因此,此处的数组仅指示对象进入的地址块。 线程对其进行了更详细的说明。 I hope this is what you were looking for. 我希望这是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM