排查这个问题之前,首先我们要知道怎么去判断 Java对象占用的内存空间大小。代码如下:
System.setProperty("java.vm.name","Java HotSpot(TM) ");
Long objSize = ObjectSizeCalculator.getObjectSize(obj);
在测试此之前,我们先定义两个对象,后续用于测试。
@Data
static class User {
private String name;
private Integer age;
}
@Data
static class Man {
private String name;
private Integer age;
private Date birth;
private String phone;
}
下面我们来测试下,null对象到底是否会占用空间:
@Test
public void testAA() {
System.setProperty("java.vm.name","Java HotSpot(TM) ");
User user = null;
log.info("null size: {}", ObjectSizeCalculator.getObjectSize(null));
log.info("user size: {}", ObjectSizeCalculator.getObjectSize(user));
log.info("eauals? {}", null == user);
}
----------------- result -----------------
null size: 0
user size: 0
eauals? true
总结下来:
null常量或者是对象的引用是 null,它们占用的内容空间是 0。
问题二:对象中的属性是 null,是否会占用内存空间?
测试代码如下:
@Test
public void testAA() {
System.setProperty("java.vm.name","Java HotSpot(TM) ");
User user = new User();
Man man = new Man();
log.info("user size: {}", ObjectSizeCalculator.getObjectSize(user));
log.info("man size: {}", ObjectSizeCalculator.getObjectSize(man));
user.setAge(18);
user.setName("Tom");
man.setAge(18);
man.setName("Tom");
log.info("user size: {}", ObjectSizeCalculator.getObjectSize(user));
log.info("man size: {}", ObjectSizeCalculator.getObjectSize(man));
}
----------------- result -----------------
user size: 24
man size: 32
user size: 88
man size: 96
总结
可以看出,对象中的属性为 null,会占用 4个字节的内存空间。
此内存用于存储对字段值的引用,该引用可以是对现有对象或空引用的引用.
对于存储在字段中的每个空值,需要4个或8个字节(取决于它是32位还是64位系统)。如果某个地方没有存储的东西可以告诉它,那么该对象如何知道它的字段为空?