热点JVM阵列分配 [英] Hotspot JVM array allocation

查看:60
本文介绍了热点JVM阵列分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找有关Hotspot JVM的适当文档的几天,有关阵列的分配方式.我的意思是说,数组的实际结构是什么,当在内存中分配时,它是由连续的块组成还是像树一样的结构.

I've been searching for days for proper documentation on Hotspot JVM, with regards to the way arrays are allocated (an). By this, I mean what's the actual structure of the array, when allocated in memory, is it made out of contiguous blocks or is it a tree like structure.

我需要结构来得出大小的公式(该公式将对象的大小和数组长度作为输入).从我运行的测试以及我能理解的代码中,我提出了数组是连续的结构.像对象一样,它们具有标头,用于计数器的int和用于数据的块.我的测试无法检测到使用类似树的结构所引起的结构开销,尽管我可以轻松预见到此类事件.

I need the structure to come up with a formula of the size (a formula which takes size of object and array length as inputs). From the tests I've run and from what code I could understand, I've come up with arrays being contiguous structures. Like an object, they have a header, an int for counter and then the blocks for data. My tests couldn't detect structure overhead that would be incurred by using a tree like structure, though I can easily envision such an event.

如果这里的任何人都更了解情况,我将不胜感激!我的最佳搜索结果产生了此链接: 阵列内存分配-分页 谢谢!

If anyone here is more informed, I'd greatly appreciate it! My best results searching have yielded this link: Array memory allocation - paging Thanks!

推荐答案

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

Probably a bit late, but here it goes:

数组被分配为连续的块.可以通过使用这里),这使您可以对原始内存进行本地访问.例如,int s数组的分配大小为(以字节为单位):

Arrays are allocated as contiguous blocks. The size can be derived by using the class sun.misc.Unsafe (Some great tutorial here), which gives you native access to raw memory. For example, the allocated size of an array of ints is (in bytes):

Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * length

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

Due to implementation of the hotspot-jvm, all objects are aligned to 8 or 4 bytes (depending on your platform: AMD64 or x86_32), so the actual size of an array is increased to a multiple of 8 or 4 bytes.

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

Using the unsafe class we can inspect the actual data:

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();
}

这将导致:

 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 

因此我们可以看到,从a偏移量16开始保存在little-endian中的整数.在12-16偏移量处的整数是数组的长度. 0-12的字节组成了一个神奇的数字,尽管我不太确定它是如何工作的.

So we can see, that the integers a saved in little-endian starting at offset 16. And the integer at offset 12-16 is the length of our array. The bytes at 0-12 make up some magic number, though I am not quite sure how that works.

注意

Note

我建议不要编写使用JVM属性的代码,因为它极不可移植,并且可能在两次更新之间中断.尽管如此,我认为您可以放心地假设数组是作为连续块分配的.

I would advice against writing code which uses properties of your JVM, as it is highly unportable and can probably break between updates. Nevertheless, I think you can safely assume that arrays are allocated as contiguous blocks.

这篇关于热点JVM阵列分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆