志不立,如无舵之舟,无衔之马,漂荡奔逸,终亦何所底乎。
通过前面的文章,我们知道,Java对象主要分为下面几个部分:
- 对象头
1. mark word
2. class pointer- 实例数据
- 对齐填充
- 数组长度(仅适用于数组对象)
对象头分为Mark word和 Class Pointer两部分。
2,3,4的内容都相对简单,我们可以一笔带过。但是对于对象头的其中两部分内容,有点丈二和尚之感。
今天我们就来聊一聊他们。
1. 透过Object的定义看对象头
首先我们先来通过源代码来大概看一下对象所具有的特点。
毋庸置疑,要想去了解对象的概况,那必须得从Object看起。
Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
(Object是任何类的父类。包括数组在内的所有对象,都要实现该类的方法)
其内部的方法主要有:
修饰符和返回类型 | 方法名 | 描述 |
---|---|---|
protected Object | clone() | |
boolean | equals(Object obj) | |
Class<?> | getClass() | |
int | hashCode() | 用于确定身份 |
void | notify()/notifyAll() | 并发相关 |
void | wait()及其重载方法 | 并发相关 |
String | toString() | |
protected void | finalize() | GC相关 |
根据对Object的分析,现在换个角度,如果让我们来设计对象头,我们会如何来标记这些内容呢?
Java涉及到并发,自然就绕不过锁这个话题。
2. Java中锁的简述
这里为了避免有些读者陷入困惑,先提前交代一些锁的内容:
Java中的锁主要分为以下几种:
JVM中加锁的四种状态(由低到高的次序):
- 无锁状态;
- 偏向锁(BiasedLocking)状态;
- 轻量级锁(ThinLocking)状态;
- 重量级锁(FatLocking)状态;
锁的等级只能升级,不可以降级(单向的)。目的是为了提高获得锁和释放锁的效率。
那很显然,在锁的部分要分为两部分:
- 有没有锁,即:有锁or无锁
- 什么锁(one of 偏向锁,轻量级锁,重量级锁);
有必要说一句,这里将会根据锁的等级,来记录不同的内容。同时在不同状态下,记录的内容也会相应地进行变化。
(毕竟在大小的限制,必须要做到主次分明)
接下来,让我们来看一下JDK内部是怎么处理对象头的。
PS:一切以源码为基准。
这部分内容定义在该文件中vm/oops/markOop.hpp