• java 类内存分配计算


         因为跟同事大哥一起看一个社区的jira,不得不恶补了一下java的类内存分配与使用计算方法。原文请参照http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html 。不得不说,一件事情做进去真的越来越复杂。

         在c和c++中,程序员可以自由的操纵内存数据,包括内存分配,内存释放等等,在java中这些繁琐(或者也可以说其实不错)的特性完全由虚拟机搞定,不用再管内存分配回收,看起来相当爽,但是到底类占用了多少空间,如何计算,对于大内存应用的程序,如hadoop hbase等有十分现实的意义。

         首先描述一下内存使用情况的分类,一种是shallow size,一种是是deep size。这里主要说明一下shallow size的计算方法。

         1、没有实力属性的类内存占用情况

         每个java类(除了数组)都占用2个字(word)的头信息(header),header的第一个字(word)内容包括有类的hash值,锁信息以及一些存活时间信息等。header的第二个字(word)包含有类的引用。

         规则(1):每个对象都要占用8字节对齐。  every object is aligned to an 8 bytes granularity

          2、类内部内存使用情况

         类头部8字节后面是属性情况,基本数据类型内存的使用情况按照我们从课本上解释的,如图:

         

         但是注意,这些类型在内存的分配是需要对齐的!对齐的原因可以参看这篇文章,http://www.devx.com/tips/Tip/13265 简单的说就是为了性能方面的考虑,int是4bytes对齐,double是8个bytes对齐。在对齐的方式上,jvm是做了优化的,即在一个类中,数据是按照以下顺序进行存储的。 

    1. doubles and longs
    2. ints and floats
    3. shorts and chars
    4. booleans and bytes
    5. references

        这样能够最小限度的减少padding,节约内存。如对一个类   

    class MyClass {
    byte a;
    int c;
    boolean d;
    long e;
    Object f;
    }

        如果按照顺序存储在内存中,则总共需要40bytes    

    [HEADER:  8 bytes]  8
    [a: 1 byte ] 9
    [padding: 3 bytes] 12
    [c: 4 bytes] 16
    [d: 1 byte ] 17
    [padding: 7 bytes] 24
    [e: 8 bytes] 32
    [f: 4 bytes] 36
    [padding: 4 bytes] 40

       按照jvm的规则存取,则只需要32bytes

    [HEADER:  8 bytes]  8
    [e: 8 bytes] 16
    [c: 4 bytes] 20
    [a: 1 byte ] 21
    [d: 1 byte ] 22
    [padding: 2 bytes] 24
    [f: 4 bytes] 28
    [padding: 4 bytes] 32

        规则(2)jvm内部存储属性是按照先保存long,double;然后int,float;然后char,short;然后byte,boolean,最后是类的引用(reference)。

       3、子类内存分布

        规则(3)子类和父类的属性不会混合在一起重排保存,父类先保存,子类后保存    

    class A {
    long a;
    int b;
    int c;
    }

    class B extends A {
    long d;
    }
    [HEADER:  8 bytes]  8
    [a: 8 bytes] 16
    [b: 4 bytes] 20
    [c: 4 bytes] 24
    [d: 8 bytes] 32

       Rule 4: Between the last field of the superclass and the first field of the subclass there must be padding to align to a 4 bytes boundary. 

       Rule 5: When the first field of a subclass is a double or long and the superclass doesn't align to an 8 bytes boundary, JVM will break rule 2 and try to put an int, then shorts, then bytes, and then references at the beginning of the space reserved to the subclass until it fills the gap. 

       rule4,rule5参照原文。

       对于数组加了4个字节的length信息,所以数组的header是12个bytes。


  • 相关阅读:
    相机篇
    ValueAnimator动画跳过中间过程的问题
    android 双向文字问题
    android让xml布局的底部跟随软键盘
    给fragment设置进入和退出动画
    android布局控件的LayoutParams
    注意点
    关于与条件判断中的顺序
    栈的反转
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/sidmeng/p/2394266.html
Copyright © 2020-2023  润新知