多个JVM进程可以共享公共类的内存吗?

时间:2012-11-21 15:17:54

标签: java memory jvm shared-libraries

我想在我的Web服务器上运行多个Java进程,每个Web应用程序一个。我正在使用一个Web框架(Play),它有很多支持类和jar文件,Java进程使用大量内存。 One Play过程显示大约225MB的“驻留私人”内存。 (我在Mac OS X上使用Java 1.7.0_05进行测试。)特定于应用程序的代码可能只有几MB。我知道典型的Java Web应用程序是添加到一个服务器进程(Tomcat等)的jar,但似乎运行Play的标准方法是作为独立的应用程序/进程。如果这些是C程序,那么200MB中的大多数将是共享库,而不是在每个应用程序中重复。有没有办法在Java中实现这一点?我看到一些关于class data sharing的页面,但这似乎只适用于核心运行时类。

4 个答案:

答案 0 :(得分:5)

此时并且使用Oracle VM,这是不可能的。

但我同意,这将是一个很好的功能,特别是因为Java拥有它需要自动完成的所有信息。

我认为JIT是我无法解决的唯一原因:JIT将运行时行为考虑在内。因此,如果应用程序A以不同于应用程序B的模式使用某些代码,则会导致在运行时生成不同的汇编程序代码。

但是,通常的“模式”是“这个代码的使用频率”。因此,如果应用A经常调用某种方法而B没有调用,他们仍然可以共享代码,因为A已经为优化/编译它付出了代价。

您可以尝试将多个应用程序作为WAR文件部署到单个VM中。但根据我的经验,这通常会导致代码无法正确清理线程本地或关闭挂钩的问题。

答案 1 :(得分:4)

答案 2 :(得分:1)

如果您正在使用支持虚拟主机的servlet容器(我相信Tomcat会这样做),您将能够使用play2-war-plugin。从Play 2.1开始,永远是root应用程序的要求将被取消,因此您可能可以使用任何servlet容器。

如果您可能需要调整war文件以将内容从WEB-INF/lib移动到您的servlet容器的lib目录,以避免再次加载所有类,这可能会影响您的应用程序,如果它使用单例或其他形式的类共享数据。

答案 3 :(得分:0)

在JVM实例之间共享内存的问题在移动平台上更为紧迫,据我所知,Android在Zygote中有一个非常聪明的解决方案:VM已初始化,然后在运行应用程序时{{1 }}编。 Linux在RAM页面上使用copy-on-write,因此大多数数据都不会重复。

如果你在Linux上运行并希望尝试使用Dalvik作为你的VM(我看到声称Dalvik上有一个tomcat的工作端口),那么移植这个解决方案是可能的。我希望这可以做大量的工作,最终可以为内存升级节省几美元。