簡體   English   中英

多個JVM進程可以共享公共類的內存嗎?

[英]Can multiple JVM processes share memory for common classes?

我想在我的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中實現這一點? 我看到一些關於類數據共享的頁面,但這似乎只適用於核心運行時類。

目前,使用Oracle VM,這是不可能的。

但我同意,這將是一個很好的功能,特別是因為Java擁有它需要自動完成的所有信息。

在我的帽子中,我認為JIT是其無法工作的唯一原因:JIT將運行時行為考慮在內。 因此,如果應用程序A使用與應用程序B不同的模式的某些代碼,則會導致在運行時生成不同的匯編程序代碼。

但是,通常的“模式”是“這個代碼的使用頻率”。 因此,如果應用程序A經常調用某種方法而B沒有,則它們仍然可以共享代碼,因為A已經為優化/編譯它付出了代價。

您可以嘗試將多個應用程序作為WAR文件部署到單個VM中。 但根據我的經驗,這通常會導致代碼無法正確清理線程本地或關閉鈎子的問題。

IBM JDK有一個jvm參數來實現這一目標。 查看@ http://www.ibm.com/developerworks/library/j-sharedclasses/

這將進入下一步: http//www.ibm.com/developerworks/library/j-multitenant-java/index.html

如果您正在使用支持虛擬主機的servlet容器(我相信Tomcat 會這樣做 ),您將能夠使用play2-war-plugin 從Play 2.1開始,永遠是root應用程序的要求將被取消,因此您可能可以使用任何servlet容器。

如果您可能需要調整war文件以將內容從WEB-INF/lib到您的servlet容器的lib目錄,以避免再次加載所有類,這可能會影響您的應用程序,如果它使用單例或其他形式的類共享數據。

在JVM實例之間共享內存的問題在移動平台上更加緊迫,據我所知,Android在Zygote中有一個非常聰明的解決方案:VM被初始化,然后在運行應用程序時它是fork() ed。 Linux在RAM頁面上使用copy-on-write,因此大多數數據不會被復制。

如果你在Linux上運行並希望嘗試使用Dalvik作為你的VM(我看到聲稱在Dalvik上有一個tomcat的工作端口),那么移植這個解決方案是可能的。 我希望這是一項大量的工作,最終可以節省幾美元的內存升級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM