上回说到Jvm内存的分配,犹如划地分治,把一块本机内存分裂成了6块。
这回我们就讲讲java堆的详细信息
java堆里也不是铁板一块,类似jvm的分治,java堆内部也好不到哪里去,大致上可以分成新生代和老年代,他们内部也不和谐,新生代又可以细分为Eden和两个survivor空间。
(按照复制算法画图并解析,其他算法请见第四章)图片如下:
是不是看着大小比例很别扭呢,没办法呀,就是按照内存大小画的-。-iii
至于他们的作用的,请关注博客,下回分解。那么回到原题,我们分解了java堆的内部情况,接下来是不是就要讲对象的分配过程了?
yeah,对象怎么分配的呢?(默认以hotspot 虚拟机为例)
在hotspot中把对象分成了对象头,实例数据和对齐填充。
在对象头中包括了两部分分别是:
1、存储对象自身的运行时数据:hashcode,GC分代年龄信息(后面会详细说明),锁标志等等。
2、类型指针:它指向它的类,没错就是关在方法区的那家伙。(个别例外没有,如数组)
在实例数据中才是干货:
定义的各种类型的字段内容(包括父类继承)。
还有一部分是对齐补充
因为内存管理的系统要求对象起始地址必须是8字节的整数倍,如果对象不能正好8字节整数倍结束只能凑了。
好了,对象的问题解决了,那么我们分配了总不能不用吧,那么我们该怎么找到我们的对象呢?
想想我们我们什么时候喜欢使用对象呢?在方法中调用!像这样XXX.xxx();对吗?
还记得方法被关在哪了吗?不记得请回去看看第一篇,谢谢。
好,你不看我就告诉你吧,方法在调用的时候被转化成栈帧,放在了方法栈里。在方法栈里调用的对象是被存储成reference数据的,这个reference可以看成一个指针,其实它也就是个指针,在JVM规范中它被规定成了指向对象的引用。我们拿到这个reference的内容就能找到对象的内存地址了。
不对!现在男女比例这个鸟样,程序猿想找对象哪有那么简单?
这就要看你是什么虚拟机了?你要是高富帅虚拟机还是简单的,你找对象估计就是这个过程:
但是屌丝虚拟机怎么办?屌丝找对象都说是个女的就行。。一般也找不着。。最后还不是都是靠媒婆(句柄)
当然它们各有各的好处,不然也不会同时存在。
高富帅虚拟机他比较省时间,直接找对象哪,不要媒婆在中间当然会节省时间,但是这种自己谈的对象感情深啊,每次对象出差都要揪心(对象在堆中GC时会被移动,每次移动都需要修改reference的数据)
屌丝虚拟机找对象是慢了点,但是大家感情都不深,对象出去出个差也不是那么揪心,只要在句柄那修改一下就好了。