Java內存泄漏及分析

對於內存泄漏,首先想到的是C語言,其實否則,java中也有各類的內存泄漏。對於java程序員,在虛擬即中,不須要爲每個新建對象去delete/free內存,不容易出現內存泄漏。可是,正php

是因爲這種機制,java中若是出現了內存泄漏將是一個很麻煩的事情,因此,對java虛擬機的內存使用的掌握能很好的幫助你排除問題。html

java內存有幾種:程序計數器,虛擬機棧,方法常量區,堆,本地方法棧,直接內存。既然分析內存泄漏,那就從這幾種內存逐一分析。java

1,程序計數器:是一個較小的內存空間,是但錢線程的字節碼行號指示器,這個不會出現內存泄漏。程序員

2,虛擬即棧:虛擬即棧拋出的異常叫作StackOverFlowError異常,指的就是棧內存溢出。虛擬機棧內存溢出主要又兩個緣由:app

(1)棧深度超過限制。jvm虛擬機對虛擬機棧是有大小限制的,若是單一性線程的棧深度超過了這限制,會拋出StackOverFlowError(其中,每一個棧的棧大小也影響這個限制的,好比在一個棧中只作一個複製操做棧深度超過10000就溢出了,可是若是一個棧中還定義了不少變量,分配了一些內存,可能超過6000就會溢出)jvm

如如下代碼(測試):測試

public class Main {private int stackLength = 1;public void stackLeak(){stackLength ++;stackLeak();}public static void main(String[]args){Main main = new Main();try{main.stackLeak();}catch(Error e){System.out.println("stack length:" + main.stackLength);throw e;}}}ui

輸出結果:url

stack length:6745Exception in thread "main" java.lang.StackOverflowError at Main.stackLeak(Main.java:12) at Main.stackLeak(Main.java:13)spa

(2)虛擬機在擴展是沒法分配到足夠的內存。

3,方法常量區。你能夠經過如下設置 -XX:PermSize=3M -XX:MaxPermSize=3M 而後在項目中加載大量的類,即會產生內存泄漏,泄漏信息爲PermGen space.或者在常量去加入大

量數據也可能會報以上錯誤。不過在jdk1.7及以上版本,經過String.intern()方法並不會把常量去擠破,由於常量區存放的是新建字符串的引用。

4,堆。堆溢出是最多見的內存溢出狀況。堆中存放的是對象的信息。若是項目中產生的對象過大,又因爲彼此引用而不能被GC回收時,就會出現內存溢出。舉例看下具體狀況:

代碼:

public class Test {public static void main(String[]args){List<People> list = new ArrayList<People>();while(true){list.add(new People());}}public static class People {public String name = "zeng";public int age = 24;}}

輸出:

java.lang.OutOfMemoryError: Java heap spaceDumping heap to java_pid16912.hprof ...Heap dump file created [76764870 bytes in 0.978 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Test.main(Test.java:12)

對於堆溢出,狀況主要有兩種,一是對象太多,java內存不夠用,這是能夠經過設置堆內存大小來調節,如:Xms500m,Xmx1000m,來給堆分配較大的內存。

第二種就不是那麼好弄,不少對象自己你是不用的,可是因爲又被其它對象引用,導出gc無法回收。

5,本地方法棧。這個不受虛擬機管理,可是操做系統本事是有內存限制的。太大也會致使內存泄漏。

6,直接內存。直接內存一樣不受虛擬機管理,一樣受操做系統限制,若是默認則和堆內存同樣,一樣也能夠本身設置,如:-XX:MaxDirectMemorySize=1000m

經過以上幾種分析:發現若是出現內存泄漏,最可能的原先是因爲堆溢出。這個也能夠從異常信息分析出

OutOfMemory -java heap space:堆溢出

OutOfMemory -PerGem space:方法常量區溢出

StackOverFlowError.:棧溢出

至於其他幾種溢出,能夠經過分析操做系統內存大小限制以及設置的堆內存,棧內存來判斷。

相關文章
相關標籤/搜索