JVM学习日记-.-JVM系列之深入JAVA堆(上)

96 阅读3分钟

“这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

引言

我们昨天接触了JVM的运行时的数据区域,学习了一些JVM的内存体系结构,大家都学废了嘛。很好,大家都学的不错啊,为了让我们的学习更加体系,全面。所以今天我们深入JAVA堆,一起探秘JAVA堆中对象分配、布局和访问的过程。

为什么学(why

深入的学习还要理由嘛?

对象的创建

神奇的new

没对象的时候怎么办?说一个(不不,我们是文明人,只动手不动口),java中,对象就是帮我们干活的,没对象怎么能行,我们一般都会new一个,我们是new了,虚拟机做了什么呢,它看到new的时候问自己问题:这个是指令的参数是否能在常量池中找到引用啊?这个类是否被(玩过啊?)加载解析初始化过啊?问完问题之后呢?先按下不表。

对象的内存分配

类加载过后,就可以为这个对象分配内存了,分配多少合适呢?如何确定呢?(先按下不表),虚拟机掐指一算,怎么着也不到一个G吧,好了内存大小算好了,眼光注视下java堆,拿出小刀划出一个小块,这块就给你了,这个要分情况讨论:

  • 堆是绝对规整的:虚拟机一看:用过的在一边,没用过的在另一边,这好办呢,中间不是有指针作为分界线嘛,我就把它移动到空闲一边差不多1个G就好了呀!这种分配方式有个专业术语:Bump the pointer(指针碰撞)。

-堆不是绝对规整的:虚拟机一看:用过的和没用过的这一块,那一块,从哪里划线都不行,怎么办呢?只见虚拟机掏出一张空闲表(Free List),瞅了半天,终于找到1块区域,安排!

那啥时候堆是规整的,一般看垃圾回收算法:如果是Serial,parnew带压缩整理的,那堆就是规整的,可以使用指针碰撞,如果是CMS,那就不是。

内存分配问题

好了,JVM知道怎么分配内存了,A来了,安排1号房,B来了,安排2号房。C来了,可能是太着急,没等安排3号房,就把当前的2号房的牌分配了(今晚注定不安宁啊),这就是我们遇到的线程安全问题了,怎么办呢?我们就告诉JVM,分配的时候先看一眼,是原来的就别分配了。但这也会有问题,就是如果人太多,JVM就眼花了,那怎么办呢?我们就得使用TLAB了(这里先按下不表,有兴趣的同学可以看看张哈希的推文)

内存分配后

内存是分配完了,就结束了嘛?答案是no!房间是有了,但谁花多少钱,那是板上钉钉的,怎么办呢,先初始化内存空间为0,这样java的实例在访问字段的时候就可以引用这些初始值了。(庙啊,妙,还有这好事,不交钱也能住)。

虚拟机做完这一切,高兴的说终于可以休息了,但是真的完事了嘛?

题外话:

我依然牵挂我那在远方的父亲,一路走好!