您的位置:首页 > 移动开发 > Objective-C

new一个Object对象占用多少内存?

2016-03-14 10:25 423 查看
ava的自动内存管理机制省却了很多编码工作,大大地提高了Java的生产力,而且JVM的性能也越来越好,特别是G1的出现,改善了垃圾回收中stop
the world的状况。

 

也许很多人都没有考虑过这个问题,new一个Object对象到底占用多少内存呢( Object obj = new Object() )?

 

这里很明确的是obj是一个指向对象的引用,引用的长度决定了Java的寻址能力,32位的JDK是4字节,64位的JDK是8字节。

 

因为obj对象没有任何数据(field),会在堆上为它分配空间吗?如果分配空间,里面存储了什么内容?

 

以面向对象的思维来分析,对象封装了数据和行为,是一个统一的整体,虽然obj对象没有数据,但是有行为(Object类定义了12个方法)。当我们执行完new操作后,obj的值为堆内存的地址,既然obj都指向一块内存了,说明是会在堆上为其分配空间的。

 

那么分配的空间有多大,存储了什么内容呢?我在JVM规范和JAVA语言规范里面没有找到相关的描述,这可能是属于JVM实现自由控制的范畴了。我们可以利用JDK自带的工具jvisualvm.exe来查看分配的空间有多大,至于存了什么内容,现在还不清楚。

 

Java代码  


/** 

 * 构造一个无任何字段的空对象占多少内存 

 * @author 杨尚川 

 */  

public class EmptyTest {  

      

    public static void main(String[] args) throws InterruptedException{  

        //加到集合中,使垃圾无法回收  

        List<EmptyObject> emptys = new ArrayList<>();  

        for(int i=0;i<100;i++){  

            emptys.add(new EmptyObject());  

        }  

        //打开jvisualvm,查看EmptyObject的大小为16字节  

        Thread.sleep(60*1000);  

    }  

    private static class EmptyObject{}  

}  

 

 

我们在这里面通过new不同的对象数(for循环次数),来分析内存占用,new 1个对象是16字节,new 2个对象是32字节,new 100个对象是1600字节,通过很多次的尝试,我们从jvisualvm里面可以看到 字节数=对象数*16 ,我们有理由相信对象数跟字节数的线性关系。从这里可以看出,jvisualvm显示的内存占用跟引用的4字节或8字节是没有关系的,也就是说,jvisualvm显示的是堆内存占用,这也很好理解,毕竟所有引用的字节占用是固定的。我的JDK是64位,8字节是引用,16字节是堆内存,总共是8+16=24字节,所以new一个Object对象占用24字节。如果JDK是32位,则new一个Object对象占用4+16=20字节,如下图所示:



 

那么分配的16字节的堆空间中存储了什么内容呢?当我们Object obj = new Object();的时候,在栈内存中有一个引用obj,他可能是32位也可能是64位,obj实质只是一个内存地址,那么当我们调用obj.xxx()的时候,JVM怎么知道obj是哪个类的实例呢?所以,可以大胆地推测,obj对象的16字节的堆内存中记录了对象属于哪个类的信息,问题是这16字节的结构是什么样的?不清楚!

 

我们研究new一个Object对象占多少内存可能没什么实际意义,因为我们在编程的时候就可以确定对象树,基本可以确定对象大小,除了变长字段,当然,变长字段我们一般也会有长度限制。所以我们真正关心的是所有数据最终的大小,也就是数据库的大小。

 

那么这种没有什么实际意义的问题为什么要研究呢?我觉得只能用三个字来形容:好奇心。好奇心是驱使我们研究技术的强大推力,当我们工作了很多年,尤其是在不重视技术的公司,我们对技术还有激情吗?保持一颗敏感好奇的心,也许技术之路可以走的更长更远。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: