美文网首页
[转]Java对象内存占用分析

[转]Java对象内存占用分析

作者: 程序员驿站 | 来源:发表于2018-05-03 17:09 被阅读47次

    [转]Java对象内存占用分析

    转载:https://segmentfault.com/a/1190000006933272
    http://www.cnblogs.com/zhanjindong/p/3757767.html

    java对象内存布局 对象头+实例数据+补充填充

    对象头

    开启指针压缩(-XX:-UseCompressedOops)的情况下(默认),对象头占用12bytes
    不开启指针压缩(-XX:+UseCompressedOops)则占用16bytes。
    

    填充对象

    Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数。例如,一个包含两个属性的对象:int和byte,并不是占用17bytes(12+4+1),而是占用24bytes(对17bytes进行8字节对齐)
    

    实例数据

    原生数据

    Type Range Default Size Example
    boolean true or false false 1 bit true, false
    byte -128 .. 127 0 8 bits 1, -90, 128
    char Unicode character or 0 to 65,536 \u0000 16 bits 'a', '\u0031', '\201', '\n', 4
    short -32,768 .. 32,767 0 16 bits 1, 3, 720, 22,000
    int -2,147,483,648 .. 2,147,483,647 0 32 bits -2, -1, 0, 1, 9
    long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 0 64 bits -4000L, -900L, 10L, 700L
    float 3.40282347 x 1038, 1.40239846 x 10-45 0.0 32 bits 1.67e200f, -1.57e-207f, .9f, 10.4F
    double 1.7976931348623157 x 10308, 4.9406564584124654 x 10-324 0.0 64 bits 1.e700d, -123457e, 37e1d
    对象引用(reference)类型在64位机器上,关闭指针压缩时占用8bytes, 开启时占用4bytes。
    

    对象内存占用

    TestObject对象有四个属性,分别为int, double, Byte, char[]类型。在打开指针压缩(-XX:+UseCompressedOops)的情况下,在64位机器上,TestObject占用的内存大小应为:
    

    12(Header) + 4(int) + 8(double) + 4(reference) = 28 (bytes),加上8字节对齐,最终的大小应为32 bytes。

    当指针压缩关闭时(-XX:-UseCompressedOops) 如果打开,在64位机器上,TestObject占用的内存大小应为:

    16(Header) + 4(int) + 8(double) + 8(reference) = 36 (bytes), 8字节对齐后为 40 bytes。

    包装类型

    Numberic Wrappers +useCompressedOops -useCompressedOops
    Byte, Boolean 16 bytes 24 bytes
    Short, Character 16 bytes 24 bytes
    Integer, Float 16 bytes 24 bytes
    Long, Double 24 bytes 24 bytes

    数组

    在64位机器,数组对象的对象头占24bytes 启动压缩了占用16字节,比普通对象占用内存多是因为需要额外的空间存储数组的长度。基础数据类型数组占用的空间包括数组对象头以及基础数据类型数据占用的内存空间
    由于对象数组中存放的是对象的引用,所以对象数组本身的大小=数组对象头+length * 引用指针大小,总大小为对象数组本身大小+存放的数据的大小之和。

    new Integer[3]:
    关闭压缩:
    Integer数组本身:24(header) + 3 * 8(Integer reference) = 48 bytes;
    总共:48 + 3 * 24(Integer) = 120 bytes。
    关闭压缩:
    Integer数组本身:24(header) + 3 * 8(Integer reference) = 48 bytes;
    总共:48 + 3 * 24(Integer) = 120 bytes。

    String

    在JDK1.7及以上版本中,String包含2个属性,一个用于存放字符串数据的char[], 一个int类型的hashcode,
    因此,在关闭指针压缩时,一个String本身需要 16(Header) + 8(char[] reference) + 4(int) = 32 bytes。
    

    除此之外,一个char[]占用24 + length * 2 bytes(8字节对齐), 即一个String占用的内存空间大小为:

    相关文章

      网友评论

          本文标题:[转]Java对象内存占用分析

          本文链接:https://www.haomeiwen.com/subject/cbllrftx.html