剛剛做完了一個項目的性能測試,“有幸”也遇到了內存泄露的案例,所以在此和大家分享一下。
主要從以下幾部分來說明,關于內存和內存泄露、溢出的概念,區分內存泄露和內存溢出;內存的區域劃分,了解GC回收機制;重點關注如何去監控和發現內存問題;此外分析出問題還要如何解決內存問題。
下面就開始本篇的內容:
第一部分 概念
眾所周知,java中的內存java虛擬機自己去管理的,他不想C++需要自己去釋放;\統地去講,java的內存分配分為兩個部分,一個是數據堆,一個是棧。程序在運行的時候一般分配數據堆,把局部的臨時的變量都放進去,生命周期和進程有關系。但是如果程序員聲明了static的變量,就直接在棧中運行的,進程銷毀了,不一定會銷毀static變量。
另外為了保證java內存不會溢出,java中有垃圾回收機制。 System.gc()即垃圾收集機制是指jvm用于釋放那些不再使用的對象所占用的內存。java語言并不要求jvm有gc,也沒有規定gc如何工作。垃圾收集的目的在于清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。
而其中,內存溢出就是你要求分配的java虛擬機內存超出了系統能給你的,系統不能滿足需求,于是產生溢出。
內存泄漏是指你向系統申請分配內存進行使用(new),可是使用完了以后卻不歸還(delete),結果你申請到的那塊內存你自己也不能再訪問,該塊已分配出來的內存也無法再使用,隨著服務器內存的不斷消耗,而無法使用的內存越來越多,系統也不能再次將它分配給需要的程序,產生泄露。一直下去,程序也逐漸無內存使用,就會溢出。
第二部分 原理
JAVA垃圾回收及對內存區劃分
在Java虛擬機規范中,提及了如下幾種類型的內存空間:
◇ 棧內存(Stack):每個線程私有的。
◇ 堆內存(Heap):所有線程公用的。
◇ 方法區(Method Area):有點像以前常說的“進程代碼段”,這里面存放了每個加載類的反射信息、類函數的代碼、編譯時常量等信息。
◇ 原生方法棧(Native Method Stack):主要用于JNI中的原生代碼,平時很少涉及。
文章來源于領測軟件測試網 http://www.kjueaiud.com/