new Object()占的的内存的大小

JavaAgent 介绍

以前在做后台服务开发的时候,SpringBoot每次改动代码都需要手动重启才能生效,感觉贼麻烦,后来使用Spring提供的一款热部署插件,它只是部分重启,相当于重新加载了我们自己写的代码,效率提高很多。后来遇到了Jrebel,它只重新加载我们修改的那个类,比Springboot热部署插件重启速度更快,连改mybatis的xml文件都能热部署,太方便了有不有!(顺便安利一下同一家公司的另一个软件XRebel,实时监控服务请求)后来又接触了BTrace,它可以线上调试代码而不需要重启项目,也是很吊的一个东西。通过了解,上面所说的几个东西都是通过Java Agent来实现的,那么Java Agent到底是啥,为啥这么吊?

在JDK1.5以后,我们可以使用agent技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的AOP功能。

Agent分为两种,一种是在主程序之前运行的Agent,一种是在主程序之后运行的Agent(前者的升级版,1.6以后提供),这两种我们都会举个

对象大小(64位机)

观察虚拟机配置

java -XX:+PrintCommandLineFlags -version

普通对象

  1. 对象头:markword 8
  2. ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节 不开启为8字节
  3. 实例数据
    1. 引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节
      Oops Ordinary Object Pointers
  4. Padding对齐,8的倍数

数组对象

  1. 对象头:markword 8
  2. ClassPointer指针同上
  3. 数组长度:4字节
  4. 数组数据
  5. 对齐 8的倍数

实验 使用JavaAgent测试Object的大小

  1. 新建项目ObjectSize (1.8)

  2. 创建文件ObjectSizeAgent

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.mashibing.jvm.agent;

    import java.lang.instrument.Instrumentation;

    public class ObjectSizeAgent {
    private static Instrumentation inst;

    public static void premain(String agentArgs, Instrumentation _inst) {
    inst = _inst;
    }

    public static long sizeOf(Object o) {
    return inst.getObjectSize(o);
    }
    }
  3. src目录下创建META-INF/MANIFEST.MF

    1
    2
    3
    Manifest-Version: 1.0
    Created-By: mashibing.com
    Premain-Class: com.mashibing.jvm.agent.ObjectSizeAgent

    注意Premain-Class这行必须是新的一行(回车 + 换行),确认idea不能有任何错误提示

  4. 打包jar文件

  5. 在需要使用该Agent Jar的项目中引入该Jar包
    project structure - project settings - library 添加该jar包

  6. 运行时需要该Agent Jar的类,加入参数:

    1
    -javaagent:C:\work\ijprojects\ObjectSize\out\artifacts\ObjectSize_jar\ObjectSize.jar
  7. 如何使用该类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    ​```java
    package com.mashibing.jvm.c3_jmm;

    import com.mashibing.jvm.agent.ObjectSizeAgent;

    public class T03_SizeOfAnObject {
    public static void main(String[] args) {
    System.out.println(ObjectSizeAgent.sizeOf(new Object()));
    System.out.println(ObjectSizeAgent.sizeOf(new int[] {}));
    System.out.println(ObjectSizeAgent.sizeOf(new P()));
    }

    private static class P {
    //8 _markword
    //4 _oop指针
    int id; //4
    String name; //4
    int age; //4

    byte b1; //1
    byte b2; //1

    Object o; //4
    byte b3; //1

    }
    }

Hotspot开启内存压缩的规则(64位机)

  1. 4G以下,直接砍掉高32位
  2. 4G - 32G,默认开启内存压缩 ClassPointers Oops
  3. 32G,压缩无效,使用64位
    内存并不是越大越好(^-^)

https://cloud.tencent.com/developer/article/1480590
https://cloud.tencent.com/developer/article/1484167

https://cloud.tencent.com/developer/article/1485795

https://cloud.tencent.com/developer/article/1482500