Hotspot JVM数组分配

Pau*_*aul 2 java jvm memory-management

我一直在寻找关于Hotspot JVM的正确文档的日子,关于数组的分配方式(一).通过这个,我的意思是什么是数组的实际结构,当在内存中分配时,它是由连续的块组成还是树状结构.

我需要结构来提出一个大小的公式(一个公式,它取对象的大小和数组长度作为输入).从我运行的测试和我能理解的代码开始,我得出的阵列是连续的结构.像对象一样,它们有一个头,一个用于计数器的int,然后是数据块.我的测试无法检测到使用树状结构会产生的结构开销,尽管我可以很容易地想到这样的事件.

如果有人在这里获得更多信息,我将非常感激!我最好的搜索结果已经产生了这个链接: 数组内存分配 - 分页 谢谢!

use*_*127 5

可能有点晚了,但在这里:

数组被分配为连续的块.可以使用类sun.misc.Unsafe(这里有一些很棒的教程)派生大小,它可以让您本机访问原始内存.例如,ints 数组的分配大小是(以字节为单位):

Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * length

由于hotspot-jvm的实现,所有对象都对齐到8或4个字节(取决于您的平台:AMD64或x86_32),因此数组的实际大小增加到8或4个字节的倍数.

使用不安全的类我们可以检查实际数据:

public static void main(String[] args) {
    //Get the unsafe object.
    Unsafe unsafe = null;
    try {
        Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        unsafe = (sun.misc.Unsafe) field.get(null);
    } catch (Exception e) {
        throw new AssertionError(e);
    }
    //define our array
    int[] data = new int[]{0,1,2,3,4,5,6,7,8,9};
    //calculate length (ignoring alignment)
    int len = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * data.length;
    //Some output formatting
    System.out.print(" 0| ");
    for(int i = 0; i < len; i++){
        //unsafe.getByte retrieves the byte in the data struct with offset i
        //This is casted to a signed integer, so we mask it to get the actual value
        String hex = Integer.toHexString(unsafe.getByte(data, i)&0xFF);
        //force a length of 2
        hex = "00".substring(hex.length()) + hex;
        //Output formatting
        System.out.print(hex);
        System.out.print(" ");
        if(i%4 == 3 && i != len -1){
            System.out.println();
            if(i < 9){
                System.out.print(" ");
            }
            System.out.print((i+1) +"| ");
        }
    }
    System.out.println();
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

 0| 01 00 00 00 
 4| 00 00 00 00 
 8| 32 02 8c f5 
12| 08 00 00 00 
16| 00 00 00 00 
20| 01 00 00 00 
24| 02 00 00 00 
28| 03 00 00 00 
32| 04 00 00 00 
36| 05 00 00 00 
40| 06 00 00 00 
44| 07 00 00 00 
Run Code Online (Sandbox Code Playgroud)

所以我们可以看到,从偏移量16开始以小端保存的整数.偏移量为12-16的整数是数组的长度.0-12的字节构成一些神奇的数字,但我不太确定它是如何工作的.

注意

我建议不要编写使用JVM属性的代码,因为它非常不可移植,并且可能在更新之间中断.不过,我认为你可以放心地假设数组被分配为连续的块.