JVM的内存占用是多少?如何最小化它?

10

我想知道在启动多个JVM进程时,JavaVM(Sun、Linux)的实际占用空间。据我所知,这些进程应该共享rt.jar(以及可能更多的内容?)。这些JVM是否共享JIT缓存(所有JVM特性相同的Classpath)?

除了设置较小的堆限制之外,我是否可以采取任何措施来减少多实例JVM的开销?

在编写应用程序时,我能做些什么吗?

我能共享内存区域吗?也许共享映射的内存块?


1
为什么需要生成多个JVM?有很多原因可以这样做,但你的原因是什么? - Tassos Bassoukos
如果您正在使用多个JVM,则应该有一个很好的理由,并且每个JVM的内存开销应该相对于您运行的机器而言非常小。 - Peter Lawrey
简单来说,在开发过程中,我会将所有东西放在一个进程中。在部署期间,我想知道是否可以将许多不同的部分放在不同的进程中以帮助稳定性而不是简单性。举个例子,如果你在Linux上启动最新版本的Chrome + Selenium,有大约25:1的几率进程会卡住并锁死。将其放在自己的进程中,如果Chrome进程运行时间太长,就杀掉它,这就是答案。另一个场景是运行C++代码,将其隔离在自己的进程中,即使出现故障也不会导致JVM崩溃,只需重新启动即可。 - Martin Kersten
有许多不同的JVM。一些比其他JVM占用更少的空间,但往往以性能为代价。 - the8472
基本上我认识的每个人今天都使用Sun VM。据我所知,其他VM在生产中几乎没有被使用。一些人在开发过程中使用增强型VM(动态替换类并调整对象图以适应变化)。 - Martin Kersten
3个回答

6

这篇文章描述了Java应用程序的组成部分。也就是说,如果你想要减少应用程序的占用空间,你需要减少以下部分:Java堆、元空间、代码缓存、直接缓冲区、线程数量等。

HotSpot JVM实例之间不会相互通信以共享数据。基本上,它们除了操作系统共享的东西(如动态库(.so)和只读内存映射文件(.jars))之外,什么都不共享。

进一步的共享取决于应用程序通过IPC机制(例如内存映射文件)提供。


我查了一下,它被称为类数据共享:http://docs.oracle.com/javase/7/docs/technotes/guides/vm/class-data-sharing.html它指出,它加载数据处理类,然后共享它以实现更快的加载。最终结果并不是我最初所希望的,但它与文件访问操作系统缓存不同。 - Martin Kersten
1
@MartinKersten 对的。CDS是一种将预加载类映射到JVM进程地址空间的机制。CDS镜像作为内存映射文件在JVM之间共享。虽然我会说它更多地是关于减少启动时间而不是减少占用空间。 - apangin

5

可能只会是一个部分回答。

JVM的内存占用是多少?

Java应用程序的完整占用由堆空间和非堆空间(我这样称呼它)组成。以下是一些驻留在非堆空间的示例:PermGen或Metaspace、代码直接分配(malloc)、NIO也使用本机内存。

如何最小化它?

堆通常占用占用了你内存占用的大部分。因此,我会从堆开始。

至于非堆空间,您可以尝试最小化:PermGen(如果您的最大值是多余的),线程堆栈(它们相当大,特别是在64位JMM中),以及代码缓存(当然,代价是性能)。

这些JVM共享JIT缓存吗?

在正常情况下(我不知道其他情况),每个进程都有自己的占用。这实际上是进程与线程之间的区别。再回到多个JVM,每个JVM都是单独的进程。

它们应该共享rt.jar吗?

如果您从同一目录(相同的安装)启动Java,则它们当然共享相同的rt.jar,但仅作为类的来源。例如,String类将根据运行的JVM数量加载多次。


4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接