目录
JOL(java object layout)java对象布局
对象头:(由2部分组成)
- 第一部分:存储对象自身的运行时数据:哈希码、GC分代年龄、锁标识状态、线程持有的锁、偏向线程ID(一般占32/64 bit)。
- 第二部分:是指针类型:指向对象的类元数据类型(即对象代表哪个类)。如果是数组对象,则对象头中还有一部分用来记录数组长度。
实例数据:实例数据用来存储对象真正的有效信息(包括父类继承下来的和自己定义的)
对齐填充:JVM要求对象起始地址必须是8字节的整数倍(8字节对齐)
使用:导包
-
org.openjdk.jol -
jol-core -
0.16
1.解析这个对象,将其转变为可以打印的格式在把他打印出来(查看对象内部信息)
- Object o=new Object();
- System.out.println(ClassLayout.parseInstance(o).toPrintable());
控制台打印:
- java.lang.Object object internals:
- OFF SZ TYPE DESCRIPTION VALUE
- 0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
- 8 4 (object header: class) 0x200001e5
- 12 4 (object alignment gap)
- Instance size: 16 bytes
- Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
2.查看对象外部信息(包括引用对象)
System.out.println(GraphLayout.parseInstance(o).toPrintable());
控制台打印
- java.lang.Object@60e53b93d object externals:
- ADDRESS SIZE TYPE PATH VALUE
- d6382698 16 java.lang.Object (object)
-
- Addresses are stable after 1 tries.
查看对象占用空间总大小
System.out.println(GraphLayout.parseInstance(o).totalSize());
格式:Student student = new Student();
理解:
- public class Test {
- public static void main(String[] args) {
- Student student = new Student();
- System.out.println(student.name);
- student=null;//只有将该对象置为null时才会被回收
- System.gc();
- }
- }
- class Student{
- String name="lili";
- //该方法用于回收资源,当System.gc();之后由垃圾回收器调用,用来回收垃圾
- @Override
- protected void finalize() throws Throwable {
- System.out.println("垃圾已被回收");
- }
- }
- lili
- 垃圾已被回收
格式:SoftReference
sr = new SoftReference<>(new Student()); 获得软引用包裹的对象:Student student = sr.get();
注意:java中使用softReference来表示软引用,如果某个对象与软引用关联,那么jvm只会在内存不足的情况下回收该对象,利用这个特性,软引用适合做缓存
格式:WeakReference
weakReference = new WeakReference<>(new Student()); 获得弱引用包裹的对象:Student student = weakReference.get();
注意:java中使用WeakReference来表示弱引用,若某对象被弱引用关联,那么不管内存是否足够,只要发生GC,都会被回收
- public class Test {
- public static void main(String[] args) {
- WeakReference
weakReference = new WeakReference<>(new Student()); - System.out.println(weakReference.get());
- System.gc();
- System.out.println(weakReference.get());
- }
- }
- class Student{
- String name="lili";
- //该方法用于回收资源,当System.gc();之后由垃圾回收器调用,用来回收垃圾
- @Override
- protected void finalize() throws Throwable {
- System.out.println("垃圾已被回收");
- }
- }
- jvmm.Student@1b6d3586
- null
- 垃圾已被回收
创建引用队列:ReferenceQueue
格式:PhantomReference
ps = new PhantomReference<>(new Student(), ro); 获得虚引用包裹的对象为空
理解:java中使用PhantomReference来表示虚引用,虚引用就形同虚设,就像某个对象没有引用与之关联一样,在任何时候,都可能被垃圾回收器回收
注意:
- public class Test {
- public static void main(String[] args) {
- ReferenceQueue
- PhantomReference
ps = new PhantomReference<>(new Student(), ro); - System.out.println(ps.get());//无法通过虚引用来获得对象的真实引用
- System.out.println(ro.poll());
- System.gc();
- while (true) {
- Reference> poll = ro.poll();//移除并返回队列的头部元素,若为空,返回null
- if (poll != null) {
- System.out.println(poll);
- }
- }
- }
- }
-
- class Student {
- String name = "lili";
- }
- null
- null
- java.lang.ref.PhantomReference@1b6d3586
由上可知在jvm进行gc之后,虚引用的对象进入了队列,然后jvm就可以通过这个队列检测到发生了垃圾回收,再进行堆外内存的处理