首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hotspot JVM数组分配

Hotspot JVM数组分配
EN

Stack Overflow用户
提问于 2012-10-04 01:51:40
回答 1查看 605关注 0票数 2

几天来,我一直在寻找关于Hotspot JVM的适当文档,关于数组的分配方式(an)。我的意思是,当分配到内存中时,数组的实际结构是什么,它是由连续的块组成的,还是树状结构。

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

如果在座的任何人消息灵通,我将不胜感激!我的最佳搜索结果是这个链接:Array memory allocation - paging,谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-28 22:35:25

可能有点晚了,但它是这样的:

数组被分配为连续的块。这个大小可以通过使用类sun.misc.Unsafe (一些很棒的教程here)来派生,这个类允许您本机访问原始内存。例如,int数组的分配大小为(以字节为单位):

Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * length

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

使用unsafe类,我们可以检查实际数据:

代码语言:javascript
复制
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();
}

这会导致:

代码语言:javascript
复制
 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 

所以我们可以看到,从偏移量16开始,整数以小端的形式保存。偏移量12-16的整数是数组的长度。0-12的字节组成了一个神奇的数字,尽管我不太确定它是如何工作的。

便笺

我建议不要编写使用JVM属性的代码,因为它是高度不可移植的,并且可能在两次更新之间中断。然而,我认为您可以安全地假设数组是作为连续块分配的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12714064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档