2010-08-19 62 views
2

在Solaris x86上的32位jvm上運行Java EE應用程序時,出現OutOfMemoryError:無法創建本機線程(或類似的東西)。
這是因爲根據我的理解,jvm沒有足夠的內存用於新線程的堆棧。如何監視內存的Java線程堆棧

我使用JConsole和VisualVM 1.3來監視應用程序,但我不知道在這些工具中調用「stackmemory」是什麼。在VisualVM中,我可以監視heappace和permgen空間,而JConsole顯示更多的內存區域。這些內存區域是否被預留用於堆棧內存?我知道這不是堆空間,但是如何處理permgen或non-heap(如JConsole中所述)

+1

機器是否有足夠的交換? – 2010-08-19 09:24:57

+0

$>交換-s 合計:1609736k字節分配+ 760644k保留= 2370380k使用,57741028k可用。 我已經將heapsize設置爲3072m,因此jvm應該可以在理論上使用另一個1024mb的非堆空間(實際上我猜測的數量少一些) – Ola 2010-08-19 09:56:23

回答

0

您也可以嘗試JProfiler。 在JProfiler中,您可以從CPU概覽視圖中的線程視圖和線程狀態中獲得提示。這裏是screencast

您還可以檢查以下來調試您的問題:(鏈接引用)如果遇到此異常,有幾件事要做。

  • 使用lsof -p PID命令(在Unix平臺 ),看 多少線程是活動的這個過程。
  • 確定操作系統定義的 每個進程的最大線程數是否有最大值 。如果限制 對應用程序而言太低,請嘗試 以提高每個進程的線程限制。
  • 檢查應用程序代碼爲 確定是否存在創建線程或連接(如 作爲LDAP連接)的代碼,而不是 將其銷燬。您可以轉儲 Java線程以查看是否存在已創建過多數量的 。
  • 如果您發現 由應用程序打開過多的連接,讓 確保任何線程的 應用程序創建被破壞。一個 企業應用程序(.ear)或Web 應用程序(.war)運行在長期運行的JVM的 之下。僅僅因爲 應用程序已完成並不意味着JVM進程結束的 。它是 迫切需要一個應用程序免費分配的任何資源 。 另一種解決方案是爲 應用程序使用線程池來 管理所需的線程。

您的代碼的某些部分可能會創建大量的線程。

嘗試在代碼中使用ThreadPoolExecutor(線程池)來限制應用程序中的線程,並相應地調整線程池大小以獲得更好的性能。