記一次生產線程數耗盡,導致內存溢出(outOfMemoryError)問題及解決


問題:

  數據源連接池線程數最大連接數最初設置300,但是一周有2-3次發生活躍連接數超過最大線程數,導致線程堵塞,服務查詢等待超時,所以運維將最大線程數調至1500,這樣導致JVM創建的線程數大大增多,原先配置的JVM內存不夠使用,導致內存溢出,無法創建線程。

解決:

  后將最大線程數調至1024,保證不會超過JVM內存限制。

 

 

系統能創建的線程數的計算公式如下:

    (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

    MaxProcessMemory 指的是一個進程的最大內存

    JVMMemory         JVM內存

    ReservedOsMemory  保留的操作系統內存

    ThreadStackSize      線程棧的大小

 

例如:運行的環境 (有必要說明一下,不同環境會有不同的結果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse 3.4

  結合上面例子我們來對公式說明一下:
  MaxProcessMemory 在32位的 windows下是 2G
  JVMMemory   eclipse默認啟動的程序內存是64M
  ReservedOsMemory  一般是130M左右
  ThreadStackSize 32位 JDK 1.6默認的stacksize 325K左右
公式如下:
  (2*1024*1024-64*1024-130*1024)/325 = 5841
公式計算所得5841,和實踐5602基本一致(有偏差是因為ReservedOsMemory不能很精確)

由公式得出結論:你給JVM內存越多,那么你能創建的線程越少,越容易發生java.lang.OutOfMemoryError: unable to create new native thread。

 

加上下面的JVM參數,測試結果如下:
  ThreadStackSize      JVMMemory                      能創建的線程數
  默認的325K    -Xms1024m -Xmx1024m      i = 2655
  默認的325K    -Xms1224m -Xmx1224m      i = 2072
  默認的325K    -Xms1324m -Xmx1324m      i = 1753
  默認的325K    -Xms1424m -Xmx1424m      i = 1435
  -Xss1024k      -Xms1424m -Xmx1424m      i = 452

 

——————————————————————————————————————————

內存泄漏導致的堆棧溢出:

java.lang.OutOfMemoryError: unable to create new native thread
【問題定位】:
對於一般的內存泄漏導致的堆棧溢出,通常的錯誤信息主要有以下幾種。
  1. java.lang.OutOfMemoryError: Java heap space
  2. java.lang.OutOfMemoryError: PermGen space
  3. java.lang.OutOfMemoryError: Requested array size exceeds VM limit
  4. java.lang.OutOfMemoryError: <reason> <stack trace> (Native method)

  前兩種是程序級別的問題,導致的堆棧溢出。這兩種情況必須對代碼問題處理解決

解決此類問題:
  1、 如果程序中有bug,導致創建大量不需要的線程或者線程沒有及時回收,那么必須解決這個bug,修改參數是不能解決問題的。
  2、 如果程序確實需要大量的線程,現有的設置不能達到要求,那么可以通過修改MaxProcessMemory,JVMMemory,ThreadStackSize這三個因素,來增加能創建的線程數:
  a. MaxProcessMemory 使用64位操作系統
  b. JVMMemory   減少JVMMemory的分配
  c. ThreadStackSize  減小單個線程的棧大小


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM