OutOfMemoryError:無法創建新的本機線程–問題神秘化

正如您從我以前的教程和案例研究中可能已經看到的那樣,要確定和解決Java Heap Space OutOfMemoryError問題可能很復雜。 我從Java EE生產系統中觀察到的常見問題之一是OutOfMemoryError:無法創建新的本機線程; HotSpot JVM無法進一步創建新的Java線程時引發的錯誤。

本文將重溫此HotSpot VM錯誤,并為您提供建議和解決策略。

如果您不熟悉HotSpot JVM,我首先建議您從高角度查看其內部HotSpot JVM內存空間 。 為了使您了解與本機(C-Heap)內存空間有關的OutOfMemoryError問題,此知識很重要。

OutOfMemoryError:無法創建新的本機線程–這是什么?

讓我們從一個基本的解釋開始。 當內部JVM本機代碼無法創建新的Java線程時,將引發此HotSpot JVM錯誤。 更準確地說,這意味著JVM本機代碼無法從操作系統(Solaris,Linux,MAC,Windows等)創建新的“本機”線程。
我們可以從如下的OpenJDK 1.6和1.7實現中清楚地看到此邏輯:

不幸的是,在這一點上,您不會得到比該錯誤更詳細的信息,沒有跡象表明為什么JVM無法從OS創建新線程…

HotSpot JVM:32位還是64位?

在進行進一步分析之前,必須從Java或Java EE環境中確定的一個基本事實是,您正在使用的HotSpot VM版本是32位還是64位。
為什么這么重要? 您將很快了解到,這個JVM問題通常與本機內存耗盡有關。 在JVM進程或OS級別。 目前,請記住:

  • 理論上,一個32位JVM進程允許增長到4 GB(在某些較舊的32位Windows版本上甚至更低)。
  • 對于32位JVM進程,C堆正在與Java堆和PermGen空間競爭 ,例如C堆容量= 2-4 GB – Java堆大小 (-Xms,-Xmx)– PermGen大小(-XX :MaxPermSize)
  • 從理論上講,允許使用64位JVM進程使用大多數可用的OS虛擬內存或最多16 EB(1600萬TB)

如您所見,如果您為32位JVM進程分配了較大的Java Heap(2 GB +),則本機內存空間容量將自動減少,這為JVM本機內存分配失敗打開了方便之門。
對于64位JVM進程,從JVM C堆的角度來看,您主要關心的是操作系統物理,虛擬和交換內存的容量和可用性。

好的,但是本機內存如何影響Java線程的創建?

現在回到我們的主要問題。 另一個需要了解的JVM基本方面是,從JVM創建的Java線程需要來自操作系統的本機內存。 現在,您應該開始了解問題的根源…
高級線程創建過程如下:

  • 從Java程序和JDK請求一個新的Java線程
  • 然后,JVM本機代碼嘗試從OS創建一個新的本機線程
  • 然后,操作系統嘗試根據包括線程堆棧大小在內的屬性創建一個新的本機線程。 然后,將本地內存從OS分配(保留)到Java進程本地內存空間; 假設該進程具有足夠的地址空間(例如32位進程)來滿足請求
  • 如果32位Java進程大小耗盡了其內存地址空間,例如2 GB,3 GB或4 GB進程大小限制,則OS將拒絕任何進一步的本機線程和內存分配
  • 如果操作系統的虛擬內存已耗盡(包括Solaris交換空間耗盡),則操作系統還將拒絕任何進一步的線程和本機內存分配,因為對堆棧的線程訪問可能會產生SIGBUS錯誤,從而使JVM崩潰* http://bugs.sun .com / view_bug.do?bug_id = 6302804

綜上所述:

  • 創建Java線程需要從OS獲得可用的本機內存。 適用于32位和64位JVM進程
  • 對于32位JVM,創建Java線程還需要C-Heap或進程地址空間中可用的內存

問題診斷

既然您對本地內存和JVM線程的創建有了更好的了解,現在是時候來看看您的問題了。 首先,我建議您遵循以下分析方法:

  1. 確定您使用的是HotSpot 32位還是64位JVM
  2. 觀察到問題時,請進行JVM線程轉儲,并確定有多少個活動線程
  3. 在OOM問題復制之前和期間密切監視Java進程大小利用率
  4. 在OOM問題復制之前和期間,密切監視OS虛擬內存利用率; 如果使用Solaris OS,則包括交換內存空間利用率

根據上述適當的數據收集將使您可以收集適當的數據點,從而使您可以進行第一級調查。 下一步將是研究可能的問題模式,并確定哪種模式適用于您的問題案例。

問題模式1 – C堆耗盡(32位JVM)

根據我的經驗,OutOfMemoryError:對于32位JVM進程,無法創建新的本機線程是很常見的。 與C堆容量相比創建太多線程時,經常會出現此問題。 JVM線程轉儲分析和Java進程大小監視將使您確定是否是原因。

問題模式2 –操作系統虛擬內存耗盡(64位JVM)

在這種情況下,操作系統虛擬內存已完全耗盡。 這可能是由于一些64位JVM進程占用了大量內存,例如10 GB +和/或其他占用大量內存的流氓進程。 同樣,Java進程大小和OS虛擬內存監視將使您確定是否是原因。

問題模式3 –操作系統虛擬內存耗盡(32位JVM)

第三種情況不那么頻繁,但仍然可以觀察到。 診斷可能會稍微復雜一些,但是關鍵的分析點是確定哪些進程導致了OS虛擬內存的全部耗盡。 您的32位JVM進程可能是源,也可能是受害者,例如使用大多數OS虛擬內存的流氓進程,并阻止您的32位JVM進程為其線程創建過程保留更多的本機內存。

請注意,當Solaris上的OS虛擬內存或交換空間用盡時,此問題也可能表現為完全JVM崩潰(如下示例所示)。

#
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
#
#  Internal Error (allocation.cpp:166), pid=2290, tid=27
#  Error: ChunkPool::allocate
#
# JRE version: 6.0_24-b07
# Java VM: Java HotSpot(TM) Server VM (19.1-b02 mixed mode solaris-sparc )
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#---------------  T H R E A D  ---------------Current thread (0x003fa800):  JavaThread "CompilerThread1" daemon [_thread_in_native, id=27, stack(0x65380000,0x65400000)]Stack: [0x65380000,0x65400000],  sp=0x653fd758,  free space=501k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
………………

本機內存耗盡:是癥狀還是根本原因?

現在,您了解了您的問題,并且知道了要處理的問題模式。 您現在準備提供解決問題的建議……是嗎?

您的工作尚未完成,請記住,此JVM OOM事件通常只是問題實際根源的“癥狀”。 根本原因通常更深,因此在向客戶提供建議之前,我建議您確實進行更深入的分析。 您要做的最后一件事就是簡單地解決并掩蓋癥狀。 僅當您對根本原因和生產環境容量要求有充分了解后,才應考慮采用諸如增加操作系統物理/虛擬內存或將所有JVM進程升級到64位之類的解決方案。

下一個要回答的基本問題是,發生OutOfMemoryError時有多少個線程處于活動狀態? 根據我在Java EE生產系統中的經驗,最常見的根本原因實際上是應用程序和/或Java EE容器在遇到不滿意的路徑(例如卡在遠程IO調用中的線程)時試圖在給定的時間創建太多線程在這種情況下,當嘗試滿足傳入的客戶端請求時,Java EE容器可能開始創建太多線程,從而增加了C堆和本機內存分配的壓力。 最重要的是,在責怪JVM之前,請執行盡職調查并確定是否要處理應用程序或Java EE容器線程調優問題是根本原因。

一旦了解并解決了根本原因(線程創建的根源),您就可以調整JVM和OS內存容量,以使其具有更高的容錯能力并更好地“生存”這些突發的線程激增方案。

建議:

  • 首先執行JVM線程轉儲分析,并確定所有活動線程的源與已建立的基準。 確定是什么原因導致Java應用程序或Java EE容器在發生故障時創建了這么多線程
  • 請確保您的監視工具密切監視Java VM進程大小和OS虛擬內存。 進行完整的根本原因分析將需要此關鍵數據
  • 不要以為您正在處理OS內存容量問題。 查看所有正在運行的進程,并確定您的JVM進程實際上是問題的根源還是其他消耗所有虛擬內存的進程的受害者
  • 重新訪問Java EE容器線程配置和JVM線程堆棧大小。 確定是否允許Java EE容器創建比JVM進程和/或OS可以處理的線程更多的線程
  • 確定您的32位JVM的Java堆大小是否太大,從而阻止JVM創建足夠的線程來滿足客戶端請求。 在這種情況下,您將不得不考慮減小Java堆大小(如果可能),垂直擴展或升級到64位JVM。

救援能力規劃分析

從我以前關于Java EE企業性能問題的十大原因的文章中可能已經看到,缺乏容量規劃分析通常是問題的根源。 任何全面的負載和性能測試活動都應正確確定生產環境的Java EE容器線程,JVM和OS本機內存需求; 包括“不快樂”路徑的影響測量。 這種方法將使您的生產環境避免此類問題,從長遠來看,可以帶來更好的系統可伸縮性和穩定性。

別忘了分享!

參考: OutOfMemoryError:無法創建新的本機線程– Java EE支持模式和Java教程博客上的JCG合作伙伴 Pierre-Hugues Charbonneau 揭開了神秘的面紗 。


翻譯自: https://www.javacodegeeks.com/2012/09/outofmemoryerror-unable-to-create-new.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371508.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371508.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371508.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

求10以內平均數的c語言,求助 給小學生出題,自己選加減乘除 做10題 10以內的數 然后統計分...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#include #include #include void Menu(void){printf("1,加法 2,減法 3,乘法 4,除法 5,退出\n");printf("請選擇題目類型:");}int Plus(void){int a, b;a rand() % 10 1;b rand() % 10 1;printf("%-2…

linux常用命令大全(轉)好東西要分享

1、ls命令 就是list的縮寫,通過ls 命令不僅可以查看linux文件夾包含的文件,而且可以查看文件權限(包括目錄、文件夾、文件權限)查看目錄信息等等 常用參數搭配: ls -a 列出目錄所有文件,包含以.開始的隱藏文件 ls -A 列出除.及.…

Cobertura和Maven:集成和單元測試的代碼覆蓋率

在姜黃項目中,我們每晚維護一個儀表板。 在儀表板上,我們收集有關項目的統計信息,包括代碼覆蓋率,findbugs分析和其他指標。 我們一直在使用Maven EMMA插件來提供代碼覆蓋,但是遇到了EMMA問題。 在對類進行檢測后&…

二分圖之匈牙利算法模版

1 /*2 匈牙利算法模版鄰接表版3 最大匹配問題4 時間復雜度&#xff1a;O (nm)5 */6 #include <cstdio>7 #include <vector>8 #include <cstring>9 using namespace std; 10 const int maxn 505; 11 vector<int> v[maxn];//x v[i][j]表示i可以與x匹配…

android 字體描邊實現,android文字描邊功能的實現

這里也要簡單說一下&#xff0c;這些小模塊并不是我原創&#xff0c;也是當時查資料找到的&#xff0c;由于時間比較久&#xff0c;原文鏈接已經忘記了&#xff0c;所以這里就不列出引用鏈接了。不過這些代碼我都修改、完善過&#xff0c;也添加了一些注釋&#xff0c;希望對大…

Factorial vs Power

題意 輸入a&#xff0c;找到滿足n!>a^n 最小的n。 數據 第一行T(1 < T < 1e5)&#xff0c;表示測試樣例數.(2 < a < 1e6)。 輸入 3 2 3 4 輸出 4 7 9 這個東西一看就知道是二分求解的&#xff0c;但是我們還是不知道怎么求的&#xff0c;我們可以吧他們取對數然…

評論:Arun Gupta撰寫的“ Java EE 6 Pocket Guide”

這是我很高興寫的評論。 我的朋友阿倫&#xff08;Arun&#xff09;發布了Java EE 6袖珍指南&#xff0c;該指南將在您訂購時盡早提供。 我很早就知道這本書&#xff0c;因為我很樂意對其進行回顧&#xff0c;也感謝有機會為本書做出一點貢獻&#xff01; Kindle版本已經可用&a…

雙android手機同步工具,手機同步軟件Android Manager使用圖文教程

類型&#xff1a;手機工具大小&#xff1a;23.6M語言&#xff1a;繁體 評分&#xff1a;6.6標簽&#xff1a;立即下載Android Manager 可透過五個簡單的步驟設定&#xff1a;步驟一. 在計算機上安裝 Android Manager請點選以下之下載按鈕或直接于計算機上輸入下載網址&#xff…

Camel:構建基于消息的應用程序

這是一篇長文章&#xff0c;包含三個單獨的主題&#xff1a; Java的Apache Camel入門 使用CamelRunner改善路線的啟動 使用Camel構建基于消息的應用程序 但是&#xff0c;由于我準備了包含所有這些材料的camel-demo-1.0.0-SNAPSHOT-project.zip &#xff0c;因此我認為將它們…

android 網易item廣告,Android仿網易嚴選商品詳情頁

仿照網易嚴選商品詳情頁面&#xff0c;整個頁面分為兩個部分&#xff0c;上面一部分是Native的ScrollView&#xff0c;下面一部分則是WebView&#xff0c;其目的是為了可以進行分步加載。滑動到ScrollView底部時&#xff0c;繼續向上拖動&#xff0c;可以加載下面的WebView部分…

freemarker,數字,日期,布爾值常用的函數

${3.4?floor} ${3.4?ceiling} ${3.45?round} ${3.45?rtf} ${3.458?string("0.##")} ${3.42?string.percent} ${3.42?string.currency} ${date?string("yyyy-MM-dd")} ${date?date} ${date?time} ${date?datetime}${true?c} ${true?string} ${…

mysql聯合索引與Where子句優化淺析

問題描述&#xff1a;把排序、條件等一個一個去除來做測試&#xff0c;結果發現問題就出在排序部分&#xff0c;去除排序時&#xff0c;執行時間由原來的48秒變成0.3x秒。于是&#xff0c;把涉及排序的字段組成一個聯合索引alter table xx add index indexname(x1,x2,x3)&#…

有效使用Eclipse的熱門提示

以下是一些技巧&#xff0c;可以幫助您避免潛在的問題并在使用Eclipse時提高工作效率。 避免安裝問題 切勿在舊版本之上安裝新版本的Eclipse。 首先重命名舊版本&#xff0c;將其移開&#xff0c;然后將新版本解壓縮到干凈的目錄中。 恢復混亂的工作空間 對于許多開發人員來…

android拍照截圖組件,Android截圖命令screencap與視頻錄制命令screenrecord(示例代碼)...

查看幫助命令[email protected] ~$ adb shell screencap -vscreencap: invalid option -- vusage: screencap [-hp] [-d display-id] [FILENAME]-h: this message-p: save the file as a png.-d: specify the display id to capture, default 0.If FILENAME ends with .png it …

usaco 2017 February platinum

1.一條路&#xff0c;兩邊都是一個1到n的全排列&#xff0c;可以把其中一個全排列的起始位置改變&#xff08;比如123可以變成231或者312&#xff09; 然后把相同的數連起來&#xff0c;求小交叉數。 先算一下交叉數&#xff0c;然后直接一步步移動&#xff0c;O1更新一下狀態就…

Hessian 源碼簡單分析

Hessian 源碼簡單分析 Hessian 是一個rpc框架&#xff0c; 我們需要先寫一個服務端&#xff0c; 然后在客戶端遠程的調用它即可。 服務端&#xff1a; 服務端通常和spring 做集成。 首先寫一個接口&#xff1a; public interface HelloService { void sayHello(String n…

Java開發人員應該知道的三件事

對于那些長期關注JavaOne 2012會議的讀者來說&#xff0c;這是一篇有趣的文章。 我最近對Java冠軍Heinz Kabutz的采訪引起了我的注意&#xff1b; 包括他的Java內存難題程序&#xff0c;從Java內存管理的角度來看&#xff0c;這很有啟發性。 采訪中有一個特別的部分吸引了我的注…

android怎么垂直居中且靠右,placeholder 靠右垂直居中/位置兼容

1.input輸入框文字靠右垂直居中。2.placehoder提示同樣靠右垂直居中。( placeholder是HTML5 input的新屬性&#xff0c;英文意思是占位符&#xff0c;它一般表示input輸入框的默認提示值。)css代碼input {text-align: right;font-size:0.3rem;width:100%;height:0.78rem;line-…

Python-Matplotlib 18 注釋

Python-Matplotlib 18 注釋 EG1: import numpy as np import matplotlib.pyplot as plty np.arange(-5, 6,1) plt.plot(y, y*y) plt.annotate(Annotate , xy(0,1) , xytext(0,5) ,arrowpropsdict(facecolorr , frac0.2 ))plt.show()轉載于:https://www.cnblogs.com/zsr0401/p/…

while和for循環

循環結構圖&#xff1a; 循環結構主要分為兩種&#xff1a;有while和for兩種循環&#xff0c;while又分為do{...}while和while{...},do...while表示先執行后判斷&#xff0c;而while循壞表示先判斷后執行&#xff0c;如果循環條件都不滿足的情況下&#xff0c;do...while至少執…