V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yang2yang
V2EX  ›  Java

Java 的 ArrayList 中有点问题求指点~~~

  •  
  •   yang2yang ·
    yang2yang · 2017-02-25 20:35:14 +08:00 · 3361 次点击
    这是一个创建于 2617 天前的主题,其中的信息可能已经有所发展或是发生改变。
        /**
         * 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;
        
        
            /**
         * 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);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    

    为什么这里 MAX_ARRAY_SIZE 会写成是 Integer.MAX_VALUE - 8?

    注释上面说是因为 header words in an array?如果这个 header words 是说下面 so 说的情况,会多 8 个字节的话?

    so上面说是因为数组对象需要多存一个 8 个字节的 size 大小,所以需要减 8?但是仅仅是在 Integer.MAX_VALUE-8 就可以省下不止 8 字节的空间把? 8 个 int 型,每个 4 个字节,应该不是可以省下 32 个字节?那不是应该-2 ?

    知乎上面说只是为了避免一些机器内存溢出....所以说这个 -8 是为了减少出错的几率?只是为了减少出错的几率,所以选择少分配一些?

    但是我看hugeCapacity函数,当 minCapacity > MAX_ARRAY_SIZE ,最后还是选择了 Integer.MAX_VALUE,来开辟数组,那么所以最大的情况下还是选择了 Integer.MAX_VALUE ?那么 MAX_ARRAY_SIZE 其实没有被使用到?

    还有 hugeCapacity 函数如果抛出 OutOfMemoryError 的话,因为 minCapacity = size+1,所以 size 原来是 Integer.MAX_VALUE ?所以还是可以会开辟出来最大的长度是 Integer.MAX_VALUE ?那么是不是 MAX_ARRAY_SIZE 其实并没有什么意义?

    其实就想问源码中 MAX_VALUE 是出于一个什么目的来进行定义的?具体是怎么使用的?为什么减 8 啊?

    10 条回复    2019-09-18 15:16:57 +08:00
    param
        1
    param  
       2017-02-25 21:04:26 +08:00 via Android
    我仿佛又听到有人在背后偷偷 @我
    LaudOak
        2
    LaudOak  
       2017-02-25 21:10:14 +08:00 via Android
    @param 蛤蛤
    yang2yang
        3
    yang2yang  
    OP
       2017-02-25 21:40:31 +08:00
    @param 为啥。。
    snnn
        4
    snnn  
       2017-02-25 21:43:08 +08:00   ❤️ 1
    oldCapacity :是你当前的长度
    minCapacity: 是你至少需要多长
    newCapacity :是你将来的长度。
    显然 oldCapacity<=minCapacity<=newCapacity<=Integer.MAX_VALUE
    一个基本原则:要让 newCapacity 尽可能的满足 minCapacity 。如果不能满足,一定要抛异常。
    什么时候 newCapacity >= MAX_ARRAY_SIZE? 答: oldCapacity + (oldCapacity >> 1) >= MAX_ARRAY_SIZE
    在这种情况下,为了防止计算溢出,干脆就让 newCapacity = MAX_ARRAY_SIZE
    但是万一这样不够呢?
    分两种情况:如果超出了 max int ,就抛异常。否则比如 minCapacity=Integer.MAX_VALUE - 2 ,那么就让它等于 Integer.MAX_VALUE
    czk1997
        5
    czk1997  
       2017-02-26 10:04:04 +08:00
    @yang2yang #3 当让是因为他用户名了,你看看 JAVA 注释……
    mikulch
        6
    mikulch  
       2017-02-26 12:06:16 +08:00
    建议楼主不要纠结这些东西
    编程是用来解决问题滴。
    yang2yang
        7
    yang2yang  
    OP
       2017-02-26 13:25:49 +08:00 via Android
    @czk1997 额,好吧。。

    @mikulch 我知道啊,但是还是想要深入理解一下
    yang2yang
        8
    yang2yang  
    OP
       2017-02-28 16:22:03 +08:00
    @snnn 谢谢,拜读好久,很有帮助。
    log4geek
        9
    log4geek  
       2017-03-23 09:39:12 +08:00
    zhgg0
        10
    zhgg0  
       2019-09-18 15:16:57 +08:00
    楼主后来弄懂了这个问题不?求解释
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2430 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:05 · PVG 09:05 · LAX 18:05 · JFK 21:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.