記憶體洩漏問題總結

2021-08-09 09:56:06 字數 1240 閱讀 6097

同事有乙個帶有少量業務邏輯然後更新資料庫某字段的需求(大約900萬資料)

執行了幾千條後,發現日誌停住了。

使用jvisualvm檢視gc,發現old區和eden區都已經滿了

第一反應是可能存在記憶體洩漏,但是看到系統初始化引數裡面最大堆記憶體大小只有512m,就覺得調大堆記憶體就應該可以了。

所以把堆記憶體大小調整為4g,eden區2g,重啟,正常執行了

第二天早上看日誌,發現又停了,日誌報記憶體溢位。檢視gc,old和eden又滿了

一定是有記憶體洩漏

show me the code:

public

class

updateutil }}

}// 顯示資料

ret.close();

con.close();

} catch (sqlexception e)

}}public

class

dbhelper catch (exception e)

return conn;}}

顯然,上面的**有兩個問題:1)在迴圈裡面建立了多個preparedstatement和resultset,但是關閉操作卻在迴圈外 2)preparedstatement和resultset的引用是乙個類靜態變數,生命週期與系統生命週期一致,那樣的話,迴圈裡面生成的物件指向的引用一直存在,這些物件就不能被gc。

使用jmap生成堆疊資訊,使用jhat分析:

印證了上面的分析,所以應該把pst和ret改為迴圈內的區域性變數。

改為迴圈內的區域性變數,再測試,好像還是不對,這preparedstatement和resultset的物件還是很多,很大,使用jmap生成堆疊資料的時候,執行了2次full gc,但是old區已使用記憶體沒見減小。

那每次用完的preparedstatement和resultset都設定為null呢?測試,還是不對

是不是connnection不關閉,引用這個connection的preparedstatement和resultset就不會被**呢?把資料量調低為50萬,執行,通過jmap觀察到了這兩個物件已經漲得很多了,full gc並沒有**他們;但是當這50萬執行完,再執行jmap的時候,發現old區一下子降下來了,preparedstatement和resultset也被立即**了。

由於preparedstatement存在connnection的引用,connnection不能被**,preparedstatement就也不能被**。

記憶體洩漏問題

這個函式動態地分配乙個整數,但從未使用刪除釋放它。因為指標和普通變數遵循相同的規則,函式結束時,pnvalue會超出範圍。因為pnvalue是唯一的變數的位址動態分配的整數,pnvalue摧毀時不再有動態分配的記憶體引用。這就是所謂的記憶體洩漏。因此,動態分配的整數不能被刪除,從而不能重新分配或重用...

C 記憶體洩漏總結

關於c 全域性變數的釋放問題,一直比較模糊,今天做了乙個測試 一 關於全域性變數的指標型別,程式在退出時,動態建立的物件還存在於記憶體中,導致記憶體洩漏 1 include 2 3 include vld.h 記憶體洩漏檢測工具 4 pragma comment lib,vld.lib 56 usi...

PHPExcel 記憶體洩漏問題

網上關於記憶體洩露的問題大都是再說匯出的時候,可這次我遇到的偏偏是匯入的時候。當然,只是針對excel2007格式的文件。我測試過,乙個大概31列 500行的文件,實行匯入之後,php會報如下錯誤 fatal error allowed memory size of 209715200 bytes ...