Memory 解释语言的虚拟内存分配远高于驻留内存分配的原因

Memory 解释语言的虚拟内存分配远高于驻留内存分配的原因,memory,Memory,我注意到许多语言都有这种情况,包括 C# 爪哇 蟒蛇 JS 以及其他许多被解释器解释的语言(通常有垃圾收集器) 当我检查系统(unix)-任何系统(我在许多不同的服务器上尝试过)上的内存使用情况时。我可以看到分配的虚拟内存和驻留内存(实际被占用的实际物理内存)之间的巨大差异 这不是一个C语言或C++语言的例子。 例如,一个使用30mb驻留内存的java应用程序可以使用2gb的虚拟内存,其他解释语言也是如此。当然,这并不是每次都会发生(并非所有情况下差别都很大),但在大多数情况下,差别相当大

我注意到许多语言都有这种情况,包括

  • C#
  • 爪哇
  • 蟒蛇
  • JS
以及其他许多被解释器解释的语言(通常有垃圾收集器)

当我检查系统(unix)-任何系统(我在许多不同的服务器上尝试过)上的内存使用情况时。我可以看到分配的虚拟内存和驻留内存(实际被占用的实际物理内存)之间的巨大差异

<>这不是一个C语言或C++语言的例子。 例如,一个使用30mb驻留内存的java应用程序可以使用2gb的虚拟内存,其他解释语言也是如此。当然,这并不是每次都会发生(并非所有情况下差别都很大),但在大多数情况下,差别相当大

或示例(这实际上是真实数据) 一个c#应用程序使用136MB的驻留内存开发,但使用1661MB的虚拟内存开发

还有一些健壮C++应用程序的例外,例如Firefox似乎有同样的问题,据我所知,它也使用垃圾回收器 对于每个基于虚拟内存限制内存的系统来说,这都是一个问题(这实际上是一种正确的方式,因为操作系统应该保证分配给进程的虚拟内存量实际上可用于该进程)


为什么会这样?

你引用的30MB虚拟数据转换成2GB虚拟数据并不是一条普遍规律

我习惯于将Java应用程序部署到JavaEE容器(例如JBOSS)。容器本身就是一个应用程序。它将大量jar加载到驻留内存中,脱离堆。加载整个JAR,而不仅仅是所需的几个类。所有这些都有助于总驻留内存

对总驻留内存也有其他贡献。例如,创建的每个线程都会为其线程堆栈获得~1MB的内存。因此,多线程代码将占用更多内存

大多数C/C++应用程序都编译为.exe,并在操作系统控制下自行运行。没有虚拟机需要考虑,所以这对他们总是有利的。这对于您引用的所有基于VM的语言都是正确的

也许它们是多线程的不太常见,所以它们缺少这种贡献。链接共享库不同于加载jar


我认为所有这些因素都可能解释这种差异。

是的,你是正确的,这不是/every/进程的情况,但大多数情况下,确实消耗了比驻留内存多得多的vmem…我可以说总驻留内存>堆内存。这并不奇怪。它超出堆的量因应用程序而异。除此之外,它取决于引入了多少库代码。