zoukankan      html  css  js  c++  java
  • 不管你有没有对象,都带你了解下对象

    JVM的数据类型

    基本数据类型

    数值型:
      整型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
      浮点:float(4字节)、double(8字节)
    字符型:char(2字节)
    布尔型:boolean(1字节)
    

      

    引用类型(reference)

            在JDK8,64位HotSpot上, 引用数据类型(reference)都是直接指针,如果开启了压缩指针,就是4字节,否则就是8字节

    对象组成

    一个对象包含3部分数据:对象头(Object Header)、实例数据(Instance Data)、对齐填充(Padding)

    图片

    而实例对象和数组对象又有所不同

    图片

    问题

    下图是oom时自动dump的文件,通过mat打开分析,可以看到,有接近30万个对象

    本文不讨论如何分析oom,而是关注:为什么Shallow Heap列中每个对象是占用24字节?

     图片 

    User.java

    package com.qzcsbj.demo.entity;
    
    public class User {
        private  Integer id;
        private String name;
    
        public User(Integer id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

     

    对象内存布局分析

    要使用到的三个参数

    PrintFlagsFinal:打印所有参数
    
    UseCompressedOops:普通对象指针压缩,oops: ordinary object pointer
    
    UseCompressedClassPointers:类指针压缩(对象头里的类型指针Klass Pointer)
    


    另外,还需要用到JOL工具,JOL是openjdk提供的用来验证JVM的内存布局方案的,ClassLayout.parseInstance(new User(1, "qzcsbj")); 

    -XX:+PrintFlagsFinal

    默认,均为开启状态

    图片

    图片

    因为是64位(Java HotSpot(TM) 64-Bit Server VM ),所以Mark Word占8个字节

    UseCompressedClassPointers默认开启,所以Class Pointer占4个字节

    所以对象头(Object Header)占用8+4=12字节

    Integer和String分别占4个字节,所以实例数据(Instance Data)占用4+4=8字节

    为了计算机高效寻址,使用padding对齐填充为8的倍数,所以最小8的倍数值为24,所以对齐填充(Padding)占用4个字节。这里也就知道上面问题为什么是24字节了。下面继续分析。 

    -XX:+PrintFlagsFinal -XX:-UseCompressedOops -XX:-UseCompressedClassPointers图片

    图片

    因为是64位(Java HotSpot(TM) 64-Bit Server VM ),所以Mark Word占8个字节

    UseCompressedClassPointers关闭,所以Class Pointer占8个字节

    所以对象头(Object Header)占用8+8=16字节

    Integer和String分别占8个字节,所以实例数据(Instance Data)占用8+8=16字节

    总共32字节,是8的倍数,所以不需要填充

    -XX:+PrintFlagsFinal -XX:+UseCompressedOops

    开启UseCompressedOops,默认会开启UseCompressedClassPointers,会压缩klass pointer 这部分的大小,由8字节压缩至4字节,间接的提高内存的利用率图片

    图片

    因为是64位(Java HotSpot(TM) 64-Bit Server VM ),所以Mark Word占8个字节

    UseCompressedClassPointers默认开启,所以Class Pointer占4个字节

    所以对象头(Object Header)占用8+4=12字节

    Integer和String分别占4个字节,所以实例数据(Instance Data)占用4+4=8字节

    为了计算机高效寻址,使用padding对齐填充为8的倍数,所以最小8的倍数值为24,所以对齐填充(Padding)占用4个字节 

    -XX:+PrintFlagsFinal -XX:+UseCompressedOops -XX:-UseCompressedClassPointers

    图片图片

    因为是64位(Java HotSpot(TM) 64-Bit Server VM ),所以Mark Word占8个字节

    UseCompressedClassPointers关闭,所以Class Pointer占8个字节

    所以对象头(Object Header)占用8+8=16字节

    Integer和String分别占4个字节,所以实例数据(Instance Data)占用4+4=8字节

    总共24字节,是8的倍数,不需要填充 

    -XX:+PrintFlagsFinal -XX:+UseCompressedClassPointers

    UseCompressedOops默认开启

    图片

    图片 

    -XX:+PrintFlagsFinal -XX:+UseCompressedClassPointers -XX:-UseCompressedOops

    虽然开启UseCompressedClassPointers,但是依然为false,因为UseCompressedClassPointers的开启是依赖于UseCompressedOops的开启

    图片报错

    图片 

    所以,开启UseCompressedOops 也默认开启UseCompressedClassPointers(可以显示指定关闭),关闭UseCompressedOops,也默认关闭UseCompressedClassPointers(不可以显示指定开启,否则报错:Java HotSpot(TM) 64-Bit Server VM warning: UseCompressedClassPointers requires UseCompressedOops)。


    如果显示指定UseCompressedOops,UseCompressedClassPointers保持默认:

    如果关闭(-XX:-UseCompressedOops):对象头16字节(8+8,mark word和klass pointer都是占用8字节),reference占用8字节;

    如果开启(-XX:+UseCompressedOops):对象头12字节(8+4,mark word占用8字节,klass pointer占用4字节),reference占用4字节。

    bak:https://www.cnblogs.com/uncleyong/p/14008618.html

    ============================= 好好学习 ==========================
    > > > 1、咨询问题,请加作者微信: ren168632201
    > > > 2、性能测试从0到实战: https://www.cnblogs.com/uncleyong/p/12311432.html
    > > > 3、自动化测试实战: https://www.cnblogs.com/uncleyong/p/12016690.html
    > > > 4、测试基础汇总: https://www.cnblogs.com/uncleyong/p/10530261.html
    > > > 5、声明:如有侵权,请联系删除。
    ============================= 升职加薪 ==========================
  • 相关阅读:
    Intel 编译器 线程安全检查 真心的很详细 转
    当前软件设计分析
    当代并行机系统
    多人游戏服务器
    ACE源代码目录结构
    (转!)Z buffer和W buffer简介
    数据库-视图(View)详解
    推荐一个vs自带工具分析代码的复杂度
    SCOPE_IDENTITY的用法
    vs2013开发调试cocos2d-x-Lua工程项目
  • 原文地址:https://www.cnblogs.com/uncleyong/p/15202110.html
Copyright © 2011-2022 走看看