一、 请解释一下对象的创立过程
在前边 “话说 类加载过程”的文章中曾经介绍过了类加载过程
创建对象的时候会先去判断类是否曾经加载,
如果没有加载的话会先加载类,
如果曾经加载就会间接创建对象。
步骤如下:
1.class loading
2.class linking (vertification prepration resolution)
3.class initiaizing
4.申请对象内存
5.成员变量赋默认值
6.调用构造方法<init>
1. 成员变量赋初始值
2. 执行构造方法语句 (super后行)
二、 对象在内存中的布局
1. 查看虚拟机设置
java -XX:+PrintCommandLineFlags -version
-XX:+UseCompressedClassPointer 开启Class Pointer指针大小是否压缩, 默认是8字节 开启压缩之后变为4字节
-XX:+UseCompressedOops 这个是指援用类型指针大小是否压缩,这个默认也是8字节 开启压缩之后变为4字节
2. 一般对象
1. 对象头 markword 8字节
2. classPointer 压缩后4字节 不压缩8字节
classpointer指向class对象 new T() 的话 classpointer就是指向T.class 这个对象
3. 实例数据
byte:1字节
short:2 字节
char:2字节
int:4字节
float:4字节
double:8字节
long:8字节
如果是援用类型压缩后4字节 不压缩8字节
4. padding 对齐 ,对象大小总是为8的倍数个字节 如果不够就对齐
3. 数组对象
1. 对象头 markword
2. classPointer 指针 指向数组元素类型的类 比入 new int[10] 就是指向int.class
3. 数组长度 : 4字节 最长int的最大值了呗
4. 数组数据
5. padding 对齐
4. 乏味的试验 看对象大小
-
agent 字节码文件在加载到内存的时候能够用一个agent截取到二进制的字节码,而后能够对字节码进行批改,也能够获取大小

-
定义class
package vip.freeedu; import java.lang.instrument.Instrumentation; public class MyAgent { // 定义一个动态变量 存起来Instrumentation private static Instrumentation instrumentation; public static void premain(String agentArgs,Instrumentation _instrumentation){ instrumentation = _instrumentation; } // 调用getObjectSize办法获取对象大小 public static long sizeOf(Object o){ return instrumentation.getObjectSize(o); } }
-
增加META-INF/MANIFEST.MF 这一行肯定要回车换行 保障idea没有报红
Manifest-Version: 1.0 Premain-Class: vip.freeedu.MyAgent
- 打成jar包
-
新建一个我的项目 把jar包加进去 不晓得怎么加 ? 上图
-
编写测试类
public class TestSize { public static void main(String[] args) { Object o = new Object(); int[] arr = new int[1]; T t = new T(); System.out.println("object长度:"+MyAgent.sizeOf(o)); System.out.println("int[]长度:"+MyAgent.sizeOf(arr)); System.out.println("t的长度:"+MyAgent.sizeOf(t)); } } class T{ int id; int age; String name ; byte b01; float f ; long l; }
-
运行时要指定javaagent!
看后果:
```
object长度:16
// markword(8) + 压缩的classpointer(4) + 成员属性(0)+ 对齐(4)
int[]长度:16
// markword(8) + 压缩的classpointer(4) + 数组长度(4) +数组数据(0)+ 对齐(0)
t的长度:40
// markword(8) + 压缩的classpointer(4) + id(4)
// + age(4) + name(4) + b01(1) + f(4) + l(8) + 对齐(3)
```
### 三、对象头具体包含什么
这个很简单 这里简略介绍(以32位为例):
次要记住锁+垃圾回收分代年龄
无锁:001
偏差锁:101
轻量级锁:00
重量级锁:10
GC标记:11
分代年龄:4bit 最大为15 这就是GC年龄为默认为15
### 四、对象怎么定位
深刻了解java虚拟机中有一张图:
第一种:变量指向一个句柄 这个句柄指向堆对象+对象数据类型(办法区)
GC算法可能比拟快
第二种(hotspot实现):变量指向堆对象 堆对象指向对象数据类型(办法区)
这种找对象比拟快
五、对象怎么调配
这个前期垃圾回收的时候再写一篇 这里就不简明扼要了
六、Object o = new Object() 在内存占用多少字节
如果开启classpointer压缩 :
对象头 8字节 + classpointer 4字节 + 属性大小 0字节 + padding 4字节 = 16字节
如果未开启classPointer压缩
对象头 8字节 + classpointer 8字节 + 属性大小 0字节 + padding 0字节 = 16字节
答: 16字节
有问题能够留言哦,也能够公众号留言(回复快):
发表回复