Java 的 ArrayList 中有点问题求指点~~~ - V2EX
yang2yang
V2EX    Java

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

  •  
  •   yang2yang
    yang2yang Feb 25, 2017 4085 views
    This topic created in 3364 days ago, the information mentioned may be changed or developed.
     /** * 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 wordsin 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 replies    2019-09-18 15:16:57 +08:00
    param
        1
    param  
       Feb 25, 2017 via Android
    我仿佛又听到有人在背后偷偷 @我
    LaudOak
        2
    LaudOak  
       Feb 25, 2017 via Android
    @param 蛤蛤
    yang2yang
        3
    yang2yang  
    OP
       Feb 25, 2017
    @param 为啥。。
    snnn
        4
    snnn  
       Feb 25, 2017   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  
       Feb 26, 2017
    @yang2yang #3 当让是因为他用户名了,你看看 JAVA 注释……
    mikulch
        6
    mikulch  
       Feb 26, 2017
    建议楼主不要纠结这些东西
    编程是用来解决问题滴。
    yang2yang
        7
    yang2yang  
    OP
       Feb 26, 2017 via Android
    @czk1997 额,好吧。。

    @mikulch 我知道啊,但是还是想要深入理解一下
    yang2yang
        8
    yang2yang  
    OP
       Feb 28, 2017
    @snnn 谢谢,拜读好久,很有帮助。
    log4geek
        9
    log4geek  
       Mar 23, 2017
    zhgg0
        10
    zhgg0  
       Sep 18, 2019
    楼主后来弄懂了这个问题不?求解释
    About     Help     Advertise     Blog     API     FAQ     Solana     4290 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 48ms UTC 00:06 PVG 08:06 LAX 17:06 JFK 20:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86