java記憶體區域與記憶體溢出例外
一、執行階段資料區
1.程式計數器:執行緒私有,用於儲存目前所執行的指令位置
2.Java虛擬機棧:線程私有,描敘Java方法執行模型;執行方法時都會建立一個棧幀,儲存局部變量,基本類型變量,引用等資訊
3.Java本地方法堆疊:執行緒私有,為虛擬機器使用到的Native方法服務
4.Java堆:執行緒共享,是垃圾收集器的主要工作地方;儲存物件實例等
5.方法區:執行緒共享;儲存類別訊息,常數,靜態變數等
運行時常數:存放編譯時產生的各種字面量和符號參考
6.直接記憶體:機器的記憶體
二、虛擬機器物件
1.物件的建立
先檢查常量池能否定位到此類的符號引用,並檢查類別是否已經載入初始化,否則要先執行載入過程;
為物件分配記憶體:計算空間並從堆中劃分一塊連續或不連續的區域;使用的是cas+失敗重試,避免線程安全問題(因為物件創建十分頻繁,不知道當前記憶體有沒有被分配出去)
初始化記憶體空間:將分配的記憶體空間初始化0值
設定物件基本資訊:元資料、hash碼、gc等
執行java的init初始化:
2.物件的記憶體佈局
物件頭:儲存物件的hash碼、鎖定狀態等和類型指標(物件所指向類別的元資料)
實例資料:物件真正儲存的資訊
對齊填入:填入符合規則
3.物件的存取權的存取物件的存取物件:填入符合規則
3.物件的存取物件的存取物件的存取物件的存取物件的存取物件。 ,透過java棧上的reference數據,它維護了一個指向物件的引用
存取方式:句柄和直接存取
#
參數
:-Xms堆最小值;-Xmx堆最大;-XX:+HeapDumpOnOutOfMemoryError出現溢位時記憶體快照分析的是物件:可以建立大量物件來實現堆疊溢位:heap space
2.堆疊溢位 #:-Xss設定棧值堆疊深度,可以透過無限遞歸增加堆疊深度、或建立大量執行緒實作
//递归来StackOverFlowerpublic class JavaVMStackSOF {private int stackLength = 1;public void stackLeak(){ stackLength++; stackLeak(); }public static void main(String[] args)throws Throwable{ JavaVMStackSOF oom = new JavaVMStackSOF();try { oom.stackLeak(); } catch(Throwable e){ System.out.println("stack length:" + oom.stackLength);throw e; } } }# 3.方法區和常數池溢位
參數
# :-XX:PermSize方法區大小;-XX:MaxPermSize方法區最大大小在JDK1.6前,可以透過建立大量的String,虛擬機會複製物件放入常數池,從而溢出
在1.7及以後,不可以這樣,因為虛擬機器只會在常數池中保存首次出現此物件時物件的參考 方法區的溢出:方法區保存的是類別的信息,透過產生大量的動態類別來溢出,如spring其實也是透過動態代理產生的類別
public class JavaMethodAreaOOM{public static void main(String[]args){while(true){//创建大量的动态类,动态代理OOMObjectEnhancer enhancer=new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor(){public Object intercept(Object obj,Method method,Object[]args,MethodProxy proxy)throws Throwable{return proxy.invokeSuper(obj,args); }} ); enhancer.create(); }}static class OOMObject{ } }String.intern()是一個Native方法,它的作用是:如果字串常數池中已經包含一個等於此String物件的字串,則傳回代表池中這個字串的String物件;否則,將此String物件包含的字串新增至常數池中,並且傳回此String物件的參考 JDK6及先前:方法區(永久代)是單獨的,常數池在方法區內 JDK7:去永久代
public class RuntimeConstantPoolOOM{public static void main(String[]args){ String str1=new StringBuilder("计算机").append("软件").toString(); System.out.println(str1.intern()==str1); String str2=new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern()==str2); } }
這段程式碼在JDK 1.6中運行,會得到兩個false,而在JDK 1.7中運行,會得到一個true和一個false。
產生差異的原因是:在JDK 1.6中,intern()方法會把首次遇到的字串實例複製到永久代中,返回的也是永久代中這個字串實例的引用,而由StringBuilder建立的字串實例在Java堆上,所以必然不是同一個引用,將傳回false。
而JDK 1.7:intern()實作不會再複製實例,只是在常數池中記錄首次出現的實例引用,因此intern()傳回的引用和由StringBuilder建立的那個字串實例是同一個。
對str2比較回傳false是因為「java」這個字串在執行StringBuilder.toString()之前已經出現過,字串常數池中已經有它的引用了,不符合「首次出現」的原則,而「電腦軟體」這個字串則是首次出現的,因此傳回true
注意:1.7及以後保存的是首次出現的引用;理解上面的分析
# 4.本機直接記憶體
參數:-XX:MaxDirectMemorySize直接記憶體大小;預設==最大堆疊記憶體
## ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### #####
以上是java記憶體區域與記憶體溢出異常的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

禪工作室 13.0.1
強大的PHP整合開發環境

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver CS6
視覺化網頁開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。