JVM负责根据对象的大小为在Java中使用new关键字创建的对象分配堆内存。 内存分配如何在内部工作。 JVM是否维护指向下一个足够大的空闲内存块并返回它的指针,或者它通过系统调用将内存分配的责任委托给OS,如C中的malloc内部调用brk()?
答案 0 :(得分:0)
它依赖于JVM,它是一个实现细节。但它通常是通过TLAB
- 线程局部分配缓冲区完成的,比malloc
快,因为它是一个简单的指针凹凸。这是一个非常简化的解释。
答案 1 :(得分: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
对象分配在" heap"记忆,分为两个区域,称为"代和#34;。有一个年轻一代"进一步分为" Eden" (a.k.a。"托儿所")和两个"幸存者空间"。还有一个" old"或者#34;终身"生成区域,基本上包括不属于年轻一代的所有堆。
对象通常首先在Eden中分配。 "大"对于伊甸园来说太大的物品进入了终身一代。
当伊甸园满员时,所有"生活"对象,通过程序中的某个引用仍然可以访问的对象,被复制到第一个幸存者空间,然后Eden被擦除,并且指向自由Eden空间的指针被设置为空间的开头。
对象分配只是指定当前" top" Eden作为新对象的地址,而指向自由Eden内存的指针则增加了对象的大小。这在现代计算机上需要10 ns。没有相当于"免费"因为个别物品永远不会被释放;堆的整个部分被简单地擦除并且空闲区域指针被重置。 当第一个幸存者空间已满时,JVM会将其中的所有活动对象和Eden复制到另一个幸存者空间中。伊甸园和第一个幸存者空间被删除,他们的指针重置。现在,另一个幸存者空间变成了#34;旧的#34;第二个",并且该过程重复。
这是非常快速的,因为没有跟踪或标记死对象,并且编写良好的程序往往会有许多相对较小的对象,而这些对象大多不会长寿。
当物品长时间存在时,它们会被提升并且#34;从年轻一代到终身代,使用较慢的算法收集频率较低。与年轻一代相比,终身对象往往死得更快,当他们这样做时,他们的空间就变成了一个“洞”。在中间某处的自由空间。旧代垃圾收集通常涉及将活动对象彼此相邻移动以将可用内存块合并为更大的块。
这只是表面的划痕。还有更多要学习的东西。