2012-05-25 89 views
11

我想在一個Java進程中運行多個REST Web應用程序,以便在Akka的幫助下輕鬆地節省內存和擴展。我想估計每個請求處理程序消耗多少內存,並檢測整個系統的這些危險。通過Java應用程序監視自己的內存使用情況

  1. 是否有可能在該進程內幾乎實時地監視內存使用情況並找出每個請求處理程序使用了多少內存?我需要做什麼?有沒有工具?

  2. 是否有可能趕上out of memory exception並根據內存使用情況做一些事情,例如只有超出假定內存限制的請求處理程序崩潰?如果是這樣,那可能有什麼不好?

+1

這是一個棘手的問題。在這裏看到更多:http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object – biziclop

回答

4

要回答你的第一個問題,有許多工具可以用來監視內存的使用情況,但是我不知道任何將內存使用情況映射到線程的「真實」時間的應用程序。在應用程序內,您可以使用MemoryMXBeanMemoryPoolMXBeans來監視內存使用情況,

要回答第二個問題:不,不是真的。除了捕捉OOME通常是一個壞主意,主要問題是接收異常的線程可能不是真正的罪魁禍首。 OOME被拋出在進行最終分配請求的線程上。但是,有些其他線程可能是填充大部分內存的線程。另一個問題是,因爲OOME可以在任何時候拋出,所以它可能被拋入應用程序中的一些關鍵代碼中,使其處於癱瘓狀態。長話短說,你幾乎總是當你收到OOME時想重新啓動你的應用程序。

+0

感謝您的回答。所以我只能將內存映射到線程?不能做更復雜的事情? 2.我想根據內存使用情況處理OOM源的問題,所以我可以知道問題是否在我的請求處理程序中。如果不是,我可以升級異常並重新啓動整個JVM。這是一個壞主意嗎? –

+0

我不確定我在你的評論中瞭解了什麼。 1.正如我所說,我不知道任何解決方案將內存使用情況映射到程序或「真實」時間。我不明白你的意思。 – jtahlborn

+0

Ach,我誤解了你。我認爲有可能跟蹤單個組件的內存使用情況,並在捕獲OOME(誰拋出以及每個組件正在使用多少內存)時使用此信息來確定是否可以爲其餘組件安全地殺死一個組件。 –

2

您還可以添加代碼中的語句來監控空閒內存,如:

Runtime runtime = Runtime.getRuntime(); 
System.out.println("Free memory: " + runtime.freeMemory() + " bytes."); 

這是不可能來處理這個異常。問題是,如果您在通用應用程序服務器(例如tomcat)中運行所有Web服務,那麼如果出現「內存不足」異常,則JVM將停止運行。嘗試查看程序中是否有任何內存泄漏或內存處理不當。您可以在Netbeans或Eclipse中使用分析。此外,使用諸如「findbugs」或「sonar」之類的工具進行代碼分析可能會在代碼中顯示出可能的不良做法。

在任何情況下,使用有關垃圾收集或JVM內存(如-Xmx)的java選項都可以減少這些異常並提高性能。

+0

使用Runtime.freeMemory()時需要注意的一件重要事情是,它包含當前堆中的垃圾,因此可能無法準確提供您想要的內容。 –

+0

準確地說,你是對的。謝謝你的評論。但是,這在很多情況下可能會導致內存處理不佳。 – stzoannos

7

程序中使用/釋放的內存總量可以通過java.lang.Runtime.getRuntime()獲得。

運行時有幾種與內存相關的方法。以下編碼示例演示了它的用法。

package test; 

import java.util.ArrayList; 
import java.util.List; 

public class PerformanceTest { 
    private static final long MEGABYTE = 1024L * 1024L; 

    public static long bytesToMegabytes(long bytes) { 
    return bytes/MEGABYTE; 
    } 

    public static void main(String[] args) { 
    // I assume you will know how to create a object Person yourself... 
    List<Person> list = new ArrayList<Person>(); 
    for (int i = 0; i <= 100000; i++) { 
     list.add(new Person("Jim", "Knopf")); 
    } 
    // Get the Java runtime 
    Runtime runtime = Runtime.getRuntime(); 
    // Run the garbage collector 
    runtime.gc(); 
    // Calculate the used memory 
    long memory = runtime.totalMemory() - runtime.freeMemory(); 
    System.out.println("Used memory is bytes: " + memory); 
    System.out.println("Used memory is megabytes: " 
     + bytesToMegabytes(memory)); 
    } 
} 
相關問題