JVM Inst
Abstract
JAVA 字符串操作的优化。
Java 对象布局
Java Array 对象布局
Java Char Array | ||
---|---|---|
Head | Mark Word | 4 Bytes |
Class Pointer | 4 Bytes | |
Length of Array | Offset = 8 | |
Instance Data | Data of Array | |
Padding |
Data of Array 中的每个 char 占 2 Bytes.
加载Length的流程包括:
- 需要通过数组实例的基地址加载Length的值。
- 如果基地址错误,需要返回错误码。
- 如果length为0,需要返回错误码。
字符串数组的简化布局:
+------------------+ | 对象头 | // 包含元数据 +------------------+ | length (int) | // 数组长度 (2) +------------------+ | 引用1 | // 指向 "Hello" 字符串对象 +------------------+ | 引用2 | // 指向 "World" 字符串对象 +------------------+
64 位 JVM 中,对象头为 16 字节,长度占 4 字节(存储字符串长度的 int),每一个引用占用 8 字节(32 位系统中占用 4 字节)
Java String 对象布局
Java String | ||
---|---|---|
Head | Mark Word | 4 Bytes |
Class Pointer | 4 Bytes | |
Instance Data | Data of Array | Offset=8 |
Raw Data | ||
Padding |
加载Length的流程包括:
- 需要通过 String 实例的基地址加载 Length 的值。
- 如果基地址错误,需要返回错误码。
- 如果length为0,需要返回错误码。
- String 的 Length 的最低位是 TAG-bit,表示是否压缩,需要移位去除掉
字符串的简化内存布局如下所示:
+------------------+ | 对象头 | // 包含元数据 +------------------+ | length (int) | // 字符串长度 +------------------+ | char[] | // 存储字符 'H', 'e', 'l', 'l', 'o' +------------------+
对象头,16 字节,长度 4 字节,每个字符占用 2 字节(因为 UTF-16 编码)
常见对象的大小
对于基本的数据类型: boolean: 1 字节(通常在对象中占用 4 字节或 8 字节,因为对象的对齐) byte: 1 字节 char: 2 字节(UTF-16 编码) short: 2 字节 int: 4 字节 float: 4 字节 long: 8 字节 double: 8 字节
对于对象头:对象头通常占用 12 字节(在 64 位 JVM 中,可能为 16 字节,具体取决于对象对齐和是否启用了指针压缩)
对于对象:大约 12 字节(在 64 位 JVM 中,可能为 16 字节) +---------------------+ | 对象头 | // 12 字节(或 16 字节) +---------------------+ | name (String) | // 4 字节(在 32 位 JVM 中)或 8 字节(在 64 位 JVM 中) +---------------------+ | age (int) | // 4 字节 +---------------------+ | 填充 (Padding) | // 可能存在,确保对齐 +---------------------+
JInst
- 加载字符数组的长度,并检查对象的指针的合法性;
- 加载字符串对象的长度,并检查对象的指针的合法性;
- 检查给定的开始和结束点是否在合法范围内;
- 检查给定的开始和长度是否在合法范围内;
- 针对 Java 的字符串拷贝。
1 和 2 都是基于 Java 内存布局进行的加载,并在异常时返回。3 和 4 帮助检查给定的开始和结束是否在合法的长度范围内。
MemCpy Opt
Java 的对象是关于 32Bit 对齐的,而 Java 的字符存储分为 Bytes 的压缩格式和 2XBytes 的宽字符格式,