JVM系列五:(对象的创建、内存分布、对象头、agent)

577 阅读3分钟

主题:

对象的创建过程、对象的内存分布、对象头中的内容、JavaAgent机制、对象的定位
按照64位机器,内存4g-32g之间的阐述

内容: 对象的创建过程: 一个对象的创建过程简单的可以分为6步: 1.对象创建的类是否被加载进内存(使用双亲委托机制load),无的话加载该类 2.加载该类完成,进行linking(vertiy,prepare,resolution),即进行校验是否是class类,类文件格式magic魔数是否为cafe babe,prepare预处理赋默认值,resolution将引用链接为地址指针指向、常量池间接引用解析为地址引用等。 3.初始化类对象,赋初始值。 4.new 对象,申请内存空间。 5.对象赋默认值。 6.调用构造方法,字节码文件中为init,设置各属性成员变量为初始值。完成后调用构造方法中的各方法,super等,加载其父。

对象的内存分布(hotspot):

根据JVM的参数设置,对象的大小是不一样的。 java -XX:+PrintCommandLineFlags -version 可以设置calsspoint的压缩状态等

      一个对象包含的内容有:
      普通对象
      对象头(markword 8字节)
      claspoint 8字节(默认压缩为4字节)
      instance(包含对象中各属性等)
      pading 4字节 (对齐,8的倍数,cpu读取内存内容,一块一块读,对齐后可提高效率)
      
      数组对象
      对象头 (markword 8字节)
      classpoint 8字节 (默认压缩为4字节,数组中存的对象指向色其类元对象指针)
      数组大小
      数组中内容
      pading 4字节 (对齐)


对象头中的内容 

      根据对象的状态,对象头中的内容是不一样的,如上图所示,每个对象的状态不同,整行对象头中的内容也不一样。
      其中有一些标志位,标记该对象是否是锁状态,是否有偏向锁等。有identity-hashcode(如果hash未被重写),如果identity-hashcode已生成,则该对象无法被设置为偏向锁。有记录分代年龄位置,位置大小为4位,最大15。
      

JavaAgent

创建一个类,引用 java.lang.instrument.Instrumentation类
instrumentation 英文释意,钢琴调铉的意思

        
        public class ObjectSizeAgent{
            
            private static Instrumentation inst;
            //必须这样写,类似主main方法
            private staticv void main premian(String agentArgs , Instrumentation _inst){
                
                inst = _inst;
                
            }
            
            private static long getObjectSize(Object o){
            
                return inst.getObjectSize(o);
                
            }
            
        }

将上面类打为一个jar,在META-INF目录下,MANIFEST.MF 文件中头行,换行回车:
Premain-Class: ObjectSizeAgent的全类名

将打包后的jar文件引用在另一个项目中,启动该项目,需要设置jvm参数,指定 javaagent的路径(-javaagen:ObjectSizeAgent的实际路径)。
这样在class文件加载进虚拟机的时候,javaagent就会先将class文件拦截,进行各种操作。类似一个代理,拦截。

我们可以获取到某个对象的大小,操作class等等,用途很多。 getObjectSize获取的返回数值,单位为字节。