我只是想知道当一个人开始产生多个 JVM 进程时,JavaVM(Sun、Linux)的实际足迹是多少。当我记得很清楚时,那些应该分享 rt.jar (也许更远?)。这些 JVM 是否共享 JIT 缓存(所有 JVM 都具有相同的 Classpath)?
我能做些什么来减少多实例 JVM 的开销吗?(除了为堆设置更小的限制)?
在编写应用程序时我能做些什么?
我可以共享内存区域吗?也许共享映射的内存块?
我只是想知道当一个人开始产生多个 JVM 进程时,JavaVM(Sun、Linux)的实际足迹是多少。当我记得很清楚时,那些应该分享 rt.jar (也许更远?)。这些 JVM 是否共享 JIT 缓存(所有 JVM 都具有相同的 Classpath)?
我能做些什么来减少多实例 JVM 的开销吗?(除了为堆设置更小的限制)?
在编写应用程序时我能做些什么?
我可以共享内存区域吗?也许共享映射的内存块?
这篇文章描述了构成 Java 应用程序足迹的内容。也就是说,如果你想减少占用空间,你需要减少这些部分:Java Heap、Metaspace、Code Cache、直接缓冲区、线程数等。
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/