我想知道在启动多个JVM进程时,JavaVM(Sun、Linux)的实际占用空间。据我所知,这些进程应该共享rt.jar(以及可能更多的内容?)。这些JVM是否共享JIT缓存(所有JVM特性相同的Classpath)?
除了设置较小的堆限制之外,我是否可以采取任何措施来减少多实例JVM的开销?
在编写应用程序时,我能做些什么吗?
我能共享内存区域吗?也许共享映射的内存块?
我想知道在启动多个JVM进程时,JavaVM(Sun、Linux)的实际占用空间。据我所知,这些进程应该共享rt.jar(以及可能更多的内容?)。这些JVM是否共享JIT缓存(所有JVM特性相同的Classpath)?
除了设置较小的堆限制之外,我是否可以采取任何措施来减少多实例JVM的开销?
在编写应用程序时,我能做些什么吗?
我能共享内存区域吗?也许共享映射的内存块?
这篇文章描述了Java应用程序的组成部分。也就是说,如果你想要减少应用程序的占用空间,你需要减少以下部分:Java堆、元空间、代码缓存、直接缓冲区、线程数量等。
HotSpot JVM实例之间不会相互通信以共享数据。基本上,它们除了操作系统共享的东西(如动态库(.so)和只读内存映射文件(.jars))之外,什么都不共享。
进一步的共享取决于应用程序通过IPC机制(例如内存映射文件)提供。
可能只会是一个部分回答。
JVM的内存占用是多少?
Java应用程序的完整占用由堆空间和非堆空间(我这样称呼它)组成。以下是一些驻留在非堆空间的示例:PermGen或Metaspace、代码直接分配(malloc)、NIO也使用本机内存。
如何最小化它?
堆通常占用占用了你内存占用的大部分。因此,我会从堆开始。
至于非堆空间,您可以尝试最小化:PermGen(如果您的最大值是多余的),线程堆栈(它们相当大,特别是在64位JMM中),以及代码缓存(当然,代价是性能)。
这些JVM共享JIT缓存吗?
在正常情况下(我不知道其他情况),每个进程都有自己的占用。这实际上是进程与线程之间的区别。再回到多个JVM,每个JVM都是单独的进程。
它们应该共享rt.jar吗?
如果您从同一目录(相同的安装)启动Java,则它们当然共享相同的rt.jar,但仅作为类的来源。例如,String类将根据运行的JVM数量加载多次。
为了补充其他答案,这里有几篇深入的文章列出了典型的JVM内存占用值以及测量它们的方法:
https://spring.io/blog/2015/12/10/spring-boot-memory-performance
http://trustmeiamadeveloper.com/2016/03/18/where-is-my-memory-java/