潜入java内存结构
java的內存結構:
在并發編程中,多個線程之間采用共享內存模型來實現多線程之間的信息交換和數據同步.線程之間通過共享程序公共的狀態,通過讀-寫內存中公共狀態的方式來進行隱式的通信.同步指的是程序在控制多個線程之間執行程序的相對順序的機制.
java內存結構圖:
java 運行時數據區:
1,PC寄存器/程序計數器:
程序計數器本身是一個數據結構,用于保存當前正在執行的程序內存地址,由于java是支持多線程執行,所以程序執行的軌跡不可能一直都是線性執行.當多個線程交叉執行時,被中斷的程序當前執行到哪個內存地址必然要保存下來,以便用于程序的恢復.為了線程切換后能恢復到正確的執行位置,每個線程都需要有一個獨立的程序計數器,各個線程之間計數器互不影響,獨立存儲,我們稱這類內存區域為"線程私有"的內存,是線程安全的.有點類似"ThreadLocal"類.
2,java棧Java Stack
java棧總是與線程關聯起來,每當創建一個線程,JVM就會為該線程創建對應的java棧,在這個java棧中又會包含多個棧幀(Stack Frame),這些棧幀是與每個方法關聯起來的,每運行一個方法就創建一個棧幀,每個棧幀會含有一些局部變量、操作棧和方法返回值等信息.每當一個方法執行完成時,該棧幀就會彈出棧幀的元素作為這個方法的返回值,并且清除這個棧幀,java棧的棧頂的棧幀就是當前正在執行的活動棧,也就是當前正在執行的方法,PC寄存器也會指向該地址.只有這個活動的棧幀的本地變量可以被操作棧使用,當這個棧幀中調用另外一個方法時,與之對應的一個新棧幀被創建,這個新創建的棧幀被放到java棧的棧頂,變為當前的活動棧.同樣現在只有這個棧的本地變量才能被使用,當這個棧中所有指令都完成時,這個棧幀被移除java棧,剛才的那個棧幀變為活動棧幀,前面棧幀的返回值變為這個棧幀的操作棧的一個操作數.
java棧是與線程對應起來,java棧數據不是線程共有的,所有不需要關系數據不一致性,也不會出現同步鎖的問題.對這個區域規定有兩種異常狀況:
a,如果線程請求的棧深度大于虛擬機所允許的深度,將拋出StackOverflowError異常;
b,如果虛擬機可以動態擴展,如果擴展時無法申請到足夠的內存,就會拋出OutOfMemoryError異常.
在虛擬機中可以使用-Xss參數來設置棧的大小(-Xss:設置每個線程的堆棧大小)
3,java 堆Head:
堆是JVM所管理最大的一塊內存空間,是被所有java線程所共享的,不是線程安全的,在JVM啟動時創建.堆是存儲java對象的地方,所有的對象實例以及數組都要在堆上分配.java堆是GC管理的主要區域,從內存回收的角度來看,由于現在GC基本都是采用分代收集算法,所以java堆還可以分為:新生代和老年代,新生代又可以分為:一個Eden空間和兩個Survivor空間.
堆大小設置:
通過-Xmx與-Xms參數控制堆的最大和最小內存空間.新生代+老年代+持久代=JVM內存大小,持久代一般固定為64M,所以增大年輕代后,將會減小年老代大小。此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8。
4,方法區Method Area:
方法區存放了要加載的類信息(名稱、修飾符、權限等)、類中的靜態常量、類中定義為final類型的常量、類中的field信息、類中的方法信息,當在程序中通過Class對象的getName.isInterface等方法來獲取信息時,這些數據都來源于方法區.方法區是被java線程所共享的,不會被垃圾回收器GC頻繁回收,它存儲的信息相對比較穩定,在一定的條件下會被GC回收,當方法區要使用的內存超過其設置的大小時,會拋出OutOfMemoryError的錯誤信息.方法區也是堆中的一部分,就是我們通常所說的java堆中的永久區(Permanet Generation),大小可以通過參數來設置,通過-XX:PermSize指定初始值,-XX:MaxPermSize指定最大值.
5,本地方法棧Native Method Stack
本地方法棧和java棧發揮的作用非常相似,區別不過是java棧為JVM執行java方法服務,而本地方法棧為JVM執行Native方法服務.本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常.
?
轉載于:https://www.cnblogs.com/fanchengshijin/p/10100681.html
總結
以上是生活随笔為你收集整理的潜入java内存结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 渐进式迭代教学法--PHP
- 下一篇: Windows 修改hosts文件以及权