各基础数据类型在 Java 虚拟机里的内存占用

May 7, 2014

Java

最近在看Java 虚拟机规范,看了一部分了,越看越有点犯迷糊了。

在Java 编程语言里,基础数据类型有 int , short , byte , boolean , long , float , double , char 八种。其中整型有五种,long , int , short , byte , char 。在 Java 虚拟机里,也是有相对应的类型的,不过 boolean 类型在编译的时候被变成了 int 或者 byte 类型了。(在前面的博客,我有对 boolean 思考的文章,点这里 在 Java 中 boolean 类型占多少内存)。

在Java 虚拟机规范里,有这么一个说明,由于虚拟机指令码个数的限制,这个个数小于 256 ,指令码用一个 byte 能表示的数字来表示,所以个数的最大数为 256 , 再加上几个特别的预留出来的,所以个数有稍微小于 256 。

因为有个数的限制,所以的规范里说明,不能给每个类型都配备一套指令。比如加法指令,有 iadd, fadd , ladd , dadd , 对应的类型是 int , float , long , double , 而 byte 类型是没有单独给分配 badd 这样的指令的,一个 byte 类型的数据被当成了 一个 int 类型是操作,这个工作是在编译时期做的工作。

所以我个人的理解,在Java 虚拟机里,byte 和 int 的区别,除了表示的数值的范围的大小外,其实占用内存是一样的。而且对于 byte , 还会另外多出一个工作。

2015.07.31 更新。占用内存是一样的应该有个错误。在占用内存方面 byte 是一个字节,short 是两个字节,int 是四个字节,这一点是可以肯定的。只是在执行代码的时候,不管是 byte 还是 short 还是 int 都用的是 int 的指令来执行的。
占用内存的计算方式是这样的,一个类定义了100个 byte 的成员变量,在实例化这个类的时候,是会占用 100 个字节的内存(这里先忽略其他占用的内存),而如果这个类定义了 100 个 int 成员变量,它在实例化的时候,占用的 100×4 个字节的内存。

写了一个简单的代码编译后查看指令,得到的结果是这样的。

public class a{
    public static void main(String[] args){
        int in = 0;
    }
}

编译后是这样子的

public class A extends java.lang.Object{
    public A();
    Code:
        0: aload_0
        1: invokespecial #1; //Method java/lang/Object."":()V
        4: return
    public static void main(java.lang.String[]);
    Code:
        0: iconst_0
        1: istore_1
        2: return
}

再来一个 byte 的,把 int 改成 byte ,结果是一样的。int i = 0 ; 被编译成了 istore_1 ,同样 byte i = 0 ; 也编译成了 istore_1 了。有兴趣可以自己写个试一下。主要用到的命令有

javac A.java
javap -c A

--- EOF ---

评论

  1. 我也是搞程序开发的,不过我的方向是.net,java感觉难点

  2. 友链已加,欢迎多多交流技术生活

添加新评论