簡體   English   中英

在 memory 中保持最大 integer 陣列所需的空間

[英]Space required to keep largest integer array in memory

我正在審查一種算法,它保留一個整數數組,輸入的大小是動態的。 所以根據我的計算,它可能需要多達

  integer MAX_VALUE  * int size  = ?   
      2^31 integers  * 4 bytes   = ?
2147483648 integers  * 4 bytes   = 8 Gigabytes

這個計算正確嗎? JVM 會使用這么多連續的空間來存儲 int 數組還是需要考慮其他事情?

數組的理論大小為:

  • numberOfElementsInTheArray * 4 字節

  • 12 字節的標頭( int[]是一個對象)。 實際上,標題的大小取決於您使用的標志以及您正在運行的 JVM 版本

  • 4個字節來保持數組的length

  • 填充。

例如:(我將為此使用JOL ):

    int [] x = new int[10];
    for(int i=0;i<10;++i){
        x[i] = 9999;
    }
    System.out.println(GraphLayout.parseInstance((Object)x).toPrintable()); 

將 output:

 [I@7a81197dd object externals:
      ADDRESS       SIZE TYPE PATH                           VALUE
    70fe45268         56 [I                                  [9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999]

所以它有56 bytes

  • 值本身為 40(10 個整數 * 4 個字節)
  • 12 用於標題
  • 4 長度
  • 0 填充

如果將此數組更改為Integer ,情況將發生巨大變化。 Integer is an Object so you will store a reference inside the array (which could be 4 or 8 bytes, depending on UseCompressedOops flag), plus each of the Integer instances will require 2 headers (each Integer is an Object).

    Integer[] y = new Integer[10];
    for(int i=0;i<10;++i){
        y[i] = 9999;
    }

    System.out.println(GraphLayout.parseInstance((Object)y).toFootprint());

這將顯示:

   [Ljava.lang.Integer;@369f73a2d footprint:
 COUNT       AVG       SUM   DESCRIPTION
     1        56        56   [Ljava.lang.Integer;
    10        16       160   java.lang.Integer
    11                 216   (total)

216 bytes

  • 每個引用 4 個字節(我打開了UseCompressedOop ),總共 40 個字節
  • 12字節的數組頭
  • 4字節長度的數組
  • 0 字節填充

該數組中的每個引用都指向一個Integer ,每個對象都有16 bytes

  • 他們持有的內部int為 4 個字節
  • 12 字節標頭
  • 0 字節填充

數組大小最大值 < Integer.MAX_VALUE

不,您的最大值不正確。

The limit on number of elements in an array in Java is a little bit less than Integer.MAX_VALUE (2,147,483,647), depending on the version of Java, the host OS, and how Java was compiled. 請參閱 Ivan Mamontov 關於問題的這個答案為什么我不能創建一個大尺寸的數組? .

是的,最大的int數組 ≈ 8 gigs

因此,最大int數組的大小將大致為( Integer.MAX_VALUE - 8L ) * 32L位,即 68,719,476,448 位,即 8,589,934,556 個八位字節。

所以是的,大約 8 場 memory。 請記住:這是一個數組的連續memory。 所以:

  • JVM和主機操作系統可能需要做大量工作來生成這樣一個數組,具體取決於運行時 memory 的碎片程度。
  • 如果主機硬件沒有足夠的真實 memory,您將陷入虛擬 memory 中,由此產生的分頁可能會導致糟糕的性能。

如果您真的在工作中突破這些限制,請務必進行實際測試。 您可能需要考慮為非常大的 memory 設計的 Java 的替代實現,例如 Azul Systems 的Zing

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM