抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

JVM Object 的内存布局

对象的生命周期:

  1. load
    1. disk -> memory ClassLoader
    2. static initializers static fields
    3. 触发原因: new/访问静态成员/loader加载等
    4. loaded 加载完
  2. create
    1. allocate memory 分配内存
    2. constructor 构造, 注意是在 static 之后执行的.
    3. created
  3. live
    1. in use 使用. Root Set 可以找到(且被使用)
    2. invisible 不可见, 泄漏. Root Set 可以找到, 但是没有使用.
    3. unreachable 不可达. 会被回收.
  4. destroy/gc
    1. collected
    2. finalize
    3. deallocated

Object 在内存中的格式(Object Memory Layout). 注意是 HotSpot 的!! 其它虚拟机差异不会很大, 都是基于 JVM 标准的。

  • 对象头: Object Header。
  • 实例数据: Instance Data。
  • 对齐填充: 64bit HotSpot 8 字节对齐. 如果整体大小不是8的倍数, 通过 padding 补齐, 让对象在内存中比较整齐

对象头

对象头的信息是与自身定义的数据是没有关系的额外存储成本, 所以 Mark Word 被设置为一个非固定的数据结构, 以便更有效地存储数据. 它会根据对象本身的状态, 复用自己的存储空间. 由三部分组成.

Mark Word格式

4 or 8 bytes。看系统位数。

  • hashCode. 对象的 hashCode.(基于内存地址, 基于自增id)
  • age. 分代年龄. 默认15次(也是最大值)
  • 锁标志位, 3bit
    • unlocked : 01
    • biased 偏向锁 101
    • light-weight locked : 00
    • heavy-weight locked : 10
    • marked for gc : 11
  • Lock Record Address
    • 轻量级锁(指向栈中的锁记录, 线程独有的数据, 不是共享的, 线程检查如果不是指向自己就需要竞争锁)
    • 检查Mark Word是否指向当前线程的栈
  • Monitor Address. 指向对象的 Monitor
  • Forwarding Address. gc自己使用. 比如说指向下一个对象

klass: 4 or 8 bytes. 指向Object的元数据(方法区), 长度看位数.

arraylength 是数组独有的. Oop: Object Operate.

32bit系统

|----------------------------------------------------------------------------------------|--------------------|
|                                    Object Header (64 bits)                             |        State       |
|-------------------------------------------------------|--------------------------------|--------------------|
|                  Mark Word (32 bits)                  |      Klass Word (32 bits)      |                    |
|-------------------------------------------------------|--------------------------------|--------------------|
| identity_hashcode:25 | age:4 | biased_lock:1 | lock:2 |      OOP to metadata object    |       Normal       |
|-------------------------------------------------------|--------------------------------|--------------------|
|  thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:2 |      OOP to metadata object    |       Biased       |
|-------------------------------------------------------|--------------------------------|--------------------|
|               ptr_to_lock_record:30          | lock:2 |      OOP to metadata object    | Lightweight Locked |
|-------------------------------------------------------|--------------------------------|--------------------|
|               ptr_to_heavyweight_monitor:30  | lock:2 |      OOP to metadata object    | Heavyweight Locked |
|-------------------------------------------------------|--------------------------------|--------------------|
|                                              | lock:2 |      OOP to metadata object    |    Marked for GC   |
|-------------------------------------------------------|--------------------------------|--------------------|

64bit系统

|------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (128 bits)                                        |        State       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                         |    Klass Word (64 bits)     |                    |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                       ptr_to_lock_record:62                         | lock:2 |    OOP to metadata object   | Lightweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor:62                   | lock:2 |    OOP to metadata object   | Heavyweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                     | lock:2 |    OOP to metadata object   |    Marked for GC   |
|------------------------------------------------------------------------------|-----------------------------|--------------------|

注意描述. 总得来说.

  • 有严格定义
  • 不同虚拟机可能会不同
  • 分成头部和实例数据, 可能还有Padding

空 Object 多大

64bit系统下,首先肯定是 8 的倍数,而Mark Word最大占用 8byte,而Klass占用是8byte,对齐后就是16byte。

加上还有地址引用,32bit系统是4byte,64bit系统是8byte。

结论:16byte(单纯对象头,堆中) + 8byte(地址引用,栈中) = 24byte 是 Java 对象的最小值

评论