2017-04-25 60 views
0

JVM负责为基于对象大小使用Java中的new关键字创建的对象分配堆内存。 内存分配如何在内部工作。 JVM是否维护一个指向下一个足够大的可用内存块的指针并返回它,或者它通过系统调用将内存分配的责任委托给OS,就像在C内部调用brk()中的malloc一样?Java新的关键字内部结构

+1

这取决于JRE的实现。 – SLaks

+1

这个逻辑是每个JVM实现的内部。 – dasblinkenlight

+0

我认为你对此太深刻了。你不需要这些知识就可以有效地发挥作用,它可以在兔子洞的很长一段路上。 – solstinger

回答

0

它依赖于JVM,它是一个实现细节。但它通常通过TLAB - 线程本地分配缓冲区完成,因为它是一个简单的指针凹凸,所以更快,然后malloc。这是一个非常简单的解释。

0

的规范的Java实现使用的存储器分配的代战略。

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/memman.html#wp1089132 http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

对象在“堆”存储器,其被划分为两个区域称为“代”分配。有一个“年轻一代”地区被进一步分为“伊甸园”(又名“托儿所”)和两个“幸存者空间”。还有一个“旧”或“终身”的世代区域,基本上包含了年轻一代所没有的所有堆。

对象通常在伊甸第一分配。 “大”对伊甸园来说太大了的东西进入了老一代。

当伊登得到充分,所有的“活”的对象,那些仍然通过在程序中有一定的参考到达,被复制到第一生存空间,然后伊甸被删除,指针释放伊甸园空间设置为空间的开始。

对象分配是简单地指定伊甸的当前“顶部”作为新的对象的地址,并以释放伊甸存储器中的指针被增加的对象的尺寸的问题。在现代计算机上这需要10纳秒。没有相当于“免费”的东西,因为单个对象永远不会被释放;整个堆的部分被简单地擦除并且自由区域指针被重置。 当第一个幸存者空间已满时,JVM将其所有活动对象和Eden复制到另一个幸存者空间中。伊甸园和第一个幸存者空间被抹去,他们的指针重置。现在其他幸存者空间变成“第一”,旧的“第二”,并且该过程重复。

这是非常迅速的,因为死的对象是不被跟踪或标记,并精心编写的程序往往有许多相对较小的天体,其中大多数都活不长。

当物体做相处时间长了,他们得到“提升”了年轻一代向年老代,收集不经常使用较慢的算法。与年轻一代相比,老年人往往死亡的速度较慢,而当他们这样做时,他们的空间就会成为中间某处空闲空间的“洞”。旧一代垃圾收集通常包括将活动对象彼此靠近以将可用内存块合并为较大的块。

这只是一个表面的划伤。还有更多要研究。