Java类的内存对齐

时间:2017-06-10 01:25:41

标签: java memory-alignment

假设我在使用gcc编译C程序的64位计算机上。我假设sizeof(int)是8个字节,sizeof(char)是1个字节。

由于内存对齐,以下结构:

struct example{
    int a;
    char c;
}

实际上没有大小为9个字节,而是16个(两个sizeof(int)),因此它的起始地址和结束地址都可以是字大小的倍数(这里假定为8个字节)。

我想知道下面的类在Java 8中有多大:

class Node {
    int val;
    Node left, right;
    boolean flag;
 }

我基本上不确定我们是否会以8或4字节的倍数对齐。

2 个答案:

答案 0 :(得分:8)

您可以使用jol了解对象的确切布局。这是Node类程序的输出(在Oracle JDK 1.8.0_121 64位上):

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

org.example.Node object internals:
OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
     0     4         (object header)                01 00 00 00 (00000001 00000000 00000000 00000000) (1)
     4     4         (object header)                00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4         (object header)                70 22 01 f8 (01110000 00100010 00000001 11111000) (-134143376)
    12     4     int Node.val                       0
    16     1 boolean Node.flag                      false
    17     3         (alignment/padding gap)        N/A
    20     4    Node Node.left                      null
    24     4    Node Node.right                     null
    28     4         (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total

因此,对齐是8个字节。对于32位JVM,它将是4个字节。

注意,这是特定于平台的。你不应该太依赖这些信息。

答案 1 :(得分:1)

ZhekaKozlov的答案不正确。

至少在JDK8的Hotspot JVM中,无论是32位JVM还是64位,默认情况下,对齐方式均为8个字节。

(对不起,我没有足够的代表要评论,所以我不得不发布一个新答案)

尝试使用Oracle jdk-8u251 x86版本,

您可以尝试使用选项rawdat <- lapply(all_files, fromJSON) hastags <- sapply(rawdat, function(x) "tags" %in% names(rawdat)) if (any(hastags)) { songTags <- unlist(lapply(rawdat[hastags], `[[`, "tags")) songTracks <- unlist(lapply(rawdat[hastags], `[[`, "track_id")) } 启动您的(热点)JVM,它将失败并显示错误:

ObjectAlignmentInBytes = 4必须大于或等于8

有趣的旁注,如果将其设置为9,也会抱怨数字必须为2的幂。

还可以在jol上,在上面的JVM上运行此代码段,而无需设置任何显式的VM选项,

XX:ObjectAlignmentInBytes=4

它将打印

System.out.println(VM.current().details());

请注意,对齐大小未在JVM规范中定义,因此它可能因实现而异。