簡體   English   中英

如何在兩個JVM實例之間共享內存?

[英]How can I share memory between two JVM instances?

我在JVM(Scala)中構建了一個巨大的圖形,我想重復使用它,調整算法。 我不想每次都從磁盤重裝它。 有沒有辦法讓它在一個JVM中連接而從另一個JVM連接,算法正在開發中?

將圖形保存到磁盤,然后使用MappedByteBuffer將其映射到內存中。 兩個進程都應使用相同的內存,這些內存將與頁面緩存共享。

兩個JVM聽起來比它需要的更復雜。 您是否考慮過進行一種“熱部署”設置,主程序加載圖形,顯示UI,然后請求(或自動查找)要加載的jar / class文件,其中包含您的實際算法代碼? 這樣,您的算法代碼將在與圖形相同的jvm中運行,但您不必重新加載圖形只是為了重新加載新的算法實現。

更新以解決OP的問題:

以下是如何構建代碼以使您的算法可以交換的方法。 各種算法的作用並不重要,只要它們在相同的輸入數據上運行即可。 只需定義如下所示的界面,並讓您的圖算法實現它。

public interface GraphAlgorithm {
  public void doStuff(Map<whatever> myBigGraph)
}

如果您的算法將結果顯示給某種窗口小部件,您也可以將其傳遞給,或者讓doStuff()返回某種結果對象。

您是否考慮過OSGi平台? 它位於單個JVM中,但允許您在沒有平台重啟的情況下使用算法升級捆綁包。 因此,您可能擁有一個長期運行的捆綁包,其中包含大量數據結構和短期算法捆綁包,可以訪問數據。

或許使用RMI? 有一個實例作為服務器,其余實例作為客戶端?

我認為這比從磁盤重新加載要復雜得多。

您當然可以在其上創建一個接口並通過(例如) RMI公開它。

但是,我對閱讀你的帖子的初步想法是

  1. 這張圖有多大?
  2. 是否可以優化您的裝載程序?

我知道LinkedIn有一個龐大的人員和連接圖表,這些圖表一直存在於內存中,需要幾個小時才能重新加載。 但我認為這是一個非常特殊的案例。

如果構建圖形的成本很高,也許可以序列化對象。

ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(bos);
        out.writeObject(graph);
        out.flush();
        byte b[] = bos.toByteArray();
//you can use FileOutputStream instead of a ByteArrayOutputStream

然后,您可以從文件中構建對象

ByteArrayInputStream inputBuffer = new ByteArrayInputStream(b);
        ObjectInputStream inputStream = new ObjectInputStream(inputBuffer);
        try {
            Graph graph = (Graph) inputStream.readObject();

        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }

只需用FileInputStream替換ByteArrayInputStream即可

如果問題只是動態加載和運行代碼而沒有名稱沖突,那么自定義類加載器就足夠了。 對於新的運行,只需將所有類文件緩存到新的類加載器中。

您是否考慮過使用少量樣本數據來測試算法?

Terracotta在許多JVM實例之間共享內存,因此您可以輕松地將群集應用於您的系統。

嗚! 遲到了。

如果它在本地機器上,類似於映射的字節緩沖區,則有apache直接內存。 http://directmemory.apache.org/

如果您希望分發, 嘗試http://hazelcast.org/ 它被很多大型項目所使用。 當然,您的對象必須是可序列化的。

暫無
暫無

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

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