jvm 如果内存碎片不再是64位虚拟地址空间的问题,为什么某些语言中的垃圾收集器需要压缩?

lvmkulzt  于 8个月前  发布在  其他
关注(0)|答案(1)|浏览(72)

从我在这里得到的:

在64位虚拟地址空间中,内存碎片似乎不再是一个问题,那么为什么在一些流行的语言,V8 js,JVM等中使用垃圾收集器呢?在标记清除后仍然需要压缩内存以防止堆碎片?

7jmck4yq

7jmck4yq1#

(V8开发者在这里)。
地址空间碎片与VM堆碎片不同。
在32位系统上,即使总共有2-3 GB的内存可用,也不太可能分配一个256 MB的对象,因为现有的对象分散在整个地址空间中,因此再也找不到 * 连续 * 256 MB的区域。这是一个64位系统(通常)不再存在的问题。
具有垃圾收集器的VM通常以“页”的形式组织其托管堆。作为一个心理模型,您可以假设每个页面的大小为1 MB。虚拟机可以将页面添加到堆中(当它需要更多页面时),并将它们给予回操作系统(当它们为空时)。现在,可能发生的情况是,一个页面被大量使用,然后它上面的大多数对象都死了,现在整个1 MB页面只用于一个只有几个字节大小的对象。当一个应用程序经历了一个需要大量内存(因此需要很多堆页面)的阶段,然后操作完成,大多数对象变得不可访问,可能会发生堆上的大多数页面大部分是空的,只有少数/小对象使用。这是浪费记忆的一种特殊形式:VM需要保留许多堆页,但所有活动对象的总大小远小于所有堆页的总大小(从操作系统的Angular 来看,堆页的总大小又是进程正在使用的内存量的[一部分])。
这就是堆碎片化。无论你是在32位还是64位系统上运行都与此无关。而避免它的方法是使用一个“压缩”垃圾收集器,即让它将对象移动到一起,以便某些页面完全空闲,并可以返回给操作系统。
旁注:48位的地址空间(实际上是47位,其中一位是内核的)并不像最初看起来的那样不可能耗尽。当应用程序(如虚拟机)有这样的想法“哦,我们有近乎无限的地址空间,所以让我们在这个东西周围保留一个4GB的地址空间'笼子',这将允许我们玩一些有趣的性能技巧/创建一些有趣的安全保证/等等”,然后一些用例想要成千上万的东西,然后你可以在你预期之前遇到地址空间限制。

相关问题