java棧
與程序計數器同樣,java棧(虛擬機棧)也是線程私有的,其生命週期與線程相同。一般存放基本數據類型,對象引用(一個指向對象起始地址的引用指針或一個表明對象的句柄),reeturnAddress類型(指向一條字節碼指令的地址)java
棧區域有兩種異常類型:若是線程請求的棧深度大於虛擬機所容許的深度,將拋StrackOverflowError異常;若是虛擬機棧能夠動態擴展(大部分虛擬機均可動態擴展),當擴展時沒法申請到足夠的內存時會拋出OutOfMemoryError異常。hexo
-Xss(StackSpace)棧空間jvm
-Xms ,-Xmx(heap memory space)堆空間:Heap是你們最爲熟悉的區域,他是jvm用來存儲對象實例的區域,Heap在32位的系統中最大爲2G,其大小經過-Xms和-Xmx來控制,-Xms爲jvm啓動時申請的最小Heap內存,默認爲物理內存的1/64,但小於1G,-Xmx爲jvm可申請的最大的Heap內存,默認爲物理內存的1/4,通常也小於1G,默認當空餘堆內存小於40%時,jvm會最大Heap的大小到-Xmx指定大小,可經過-XX:MinHeapFreeRatio來指定這個比例,當空餘堆內存大於70%時,JVM會將Heap的大小往-Xms指定的大小調整,可經過-XX:MaxHeapFreeRatio來指定這個比例,但一般爲了不頻繁調整HeapSize的大小,將-Xms和-Xmx的值設爲相同。工具
-XX:PermSize -XX:MaxPermSize:方法區持久代大小:方法區域也是全局共享的,在必定的條件下它也會被 GC,當方法區域須要使用的內存超過其容許的大小時,會拋出 OutOfMemory的錯誤信息。spa
OutOfMemoryError異常
除了程序計數器外,虛擬機內存的其餘幾個運行時區域都有發生OutOfMemoryError(OOM)異常的可能,線程
Java Heap 溢出指針
通常的異常信息:java.lang.OutOfMemoryError:Java heap spacess對象
java堆用於存儲對象實例,咱們只要不斷的建立對象,而且保證GC Roots到對象之間有可達路徑來避免垃圾回收機制清除這些對象,就會在對象數量達到最大堆容量限制後產生內存溢出異常。生命週期
出現這種異常,通常手段是先經過內存映像分析工具(如Eclipse Memory Analyzer)對dump出來的堆轉存快照進行分析,重點是確認內存中的對象是不是必要的,先分清是由於內存泄漏(Memory Leak)仍是內存溢出(Memory Overflow)。ip
若是是內存泄漏,可進一步經過工具查看泄漏對象到GC Roots的引用鏈。因而就能找到泄漏對象時經過怎樣的路徑與GC Roots相關聯並致使垃圾收集器沒法自動回收。
若是不存在泄漏,那就應該檢查虛擬機的參數(-Xmx與-Xms)的設置是否適當。
虛擬機棧和本地方法棧溢出
若是線程請求的棧深度大於虛擬機所容許的最大深度,將拋出StackOverflowError異常。
若是虛擬機在擴展棧時沒法申請到足夠的內存空間,則拋出OutOfMemoryError異常
這裏須要注意當棧的大小越大可分配的線程數就越少。
運行時常量池溢出
異常信息:java.lang.OutOfMemoryError:PermGen space
若是要向運行時常量池中添加內容,最簡單的作法就是使用String.intern()這個Native方法。該方法的做用是:若是池中已經包含一個等於此String的字符串,則返回表明池中這個字符串的String對象;不然,將此String對象包含的字符串添加到常量池中,而且返回此String對象的引用。因爲常量池分配在方法區內,咱們能夠經過-XX:PermSize和-XX:MaxPermSize限制方法區的大小,從而間接限制其中常量池的容量。
方法區溢出
方法區用於存放Class的相關信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。
異常信息:java.lang.OutOfMemoryError:PermGen space
方法區溢出也是一種常見的內存溢出異常,一個類若是要被垃圾收集器回收,斷定條件是很苛刻的。在常常動態生成大量Class的應用中,要特別注意這點。
《深刻理解java虛擬機》