freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內容

java虛擬機詳解(編輯修改稿)

2025-07-25 08:27 本頁面
 

【文章內容簡介】 尤其是類卸載,條件相當苛刻。(Runtime Constant Pool)Class文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量表(constant_pool table),用于存放編譯期已可知的常量,這部分內容將在類加載后進入方法區(qū)(永久代)存放。但是Java語言并不要求常量一定只有編譯期預置入Class的常量表的內容才能進入方法區(qū)常量池,運行期間也可將新內容放入常量池(()方法)。運行時常量池是方法區(qū)的一部分,自然受到方法區(qū)內存的限制,當常量池無法在申請到內存時會拋出OutOfMemoryError異常。(Direct Memory)直接內存并不是虛擬機運行時數據區(qū)的一部分,它根本就是本機內存而不是VM直接管理的區(qū)域。但是這部分內存也會導致OutOfMemoryError異常出現,因此我們放到這里一起描述。,引入一種基于渠道與緩沖區(qū)的I/O方式,它可以通過本機Native函數庫直接分配本機內存,然后通過一個存儲在Java堆里面的DirectByteBuffer對象作為這塊內存的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了在Java對和本機堆中來回復制數據。顯然本機直接內存的分配不會受到Java堆大小的限制,但是即然是內存那肯定還是要受到本機物理內存(包括SWAP區(qū)或者Windows虛擬內存)的限制的,一般服務器管理員配置JVM參數時,會根據實際內存設置Xmx等參數信息,但經常忽略掉直接內存,使得各個內存區(qū)域總和大于物理內存限制(包括物理的和操作系統級的限制),而導致動態(tài)擴展時出現OutOfMemoryError異常。實戰(zhàn)OutOfMemoryError上述區(qū)域中,除了程序計數器,其他在VM Spec中都描述了產生OutOfMemoryError(下稱OOM)的情形,那我們就實戰(zhàn)模擬一下,通過幾段簡單的代碼,令對應的區(qū)域產生OOM異常以便加深認識,同時初步介紹一些與內存相關的虛擬機參數。下文的代碼都是基于Sun ,對于不同公司的不同版本的虛擬機,參數與程序運行結果可能結果會有所差別。Java堆Java堆存放的是對象實例,因此只要不斷建立對象,并且保證GC Roots到對象之間有可達路徑即可產生OOM異常。測試中限制Java堆大小為20M,不可擴展,通過參數XX:+HeapDumpOnOutOfMemoryError讓虛擬機在出現OOM異常的時候Dump出內存映像以便分析。(關于Dump映像文件分析方面的內容,可參見本文第三章《JVM內存管理:深入JVM內存異常分析與調優(yōu)》。)清單1:Java堆OOM測試/*** VM Args:Xms20m Xmx20m XX:+HeapDumpOnOutOfMemoryError* @author zzm*/public class HeapOOM {static class OOMObject {}public static void main(String[] args) {ListOOMObject list = new ArrayListOOMObject()。while (true) {(new OOMObject())。}}}運行結果:: Java heap spaceDumping heap to ...Heap dump file created [22045981 bytes in secs]VM棧和本地方法棧Hotspot虛擬機并不區(qū)分VM棧和本地方法棧,因此Xoss參數實際上是無效的,棧容量只由Xss參數設定。關于VM棧和本地方法棧在VM Spec描述了兩種異常:StackOverflowError與OutOfMemoryError,當??臻g無法繼續(xù)分配分配時,到底是內存太小還是棧太大其實某種意義上是對同一件事情的兩種描述而已,在筆者的實驗中,對于單線程應用嘗試下面3種方法均無法讓虛擬機產生OOM,全部嘗試結果都是獲得SOF異常。結果:拋出SOF異常時的堆棧深度相應縮小。,增大此方法對應幀的長度。結果:拋出SOF異常時的堆棧深度相應縮小。,打開逃逸分析和標量替換選項,使得JIT編譯器允許對象拆分后在棧中分配。結果:實際效果同第二點。清單2:VM棧和本地方法棧OOM測試(僅作為第1點測試程序)/*** VM Args:Xss128k* @author zzm*/public class JavaVMStackSOF {private int stackLength = 1。public void stackLeak() {stackLength++。stackLeak()。}public static void main(String[] args) throws Throwable {JavaVMStackSOF oom = new JavaVMStackSOF()。try {()。} catch (Throwable e) {(stack length: + )。throw e。}}}運行結果:stack length:2402Exception in thread main at (:20)at (:21)at (:21)如果在多線程環(huán)境下,不斷建立線程倒是可以產生OOM異常,但是基本上這個異常和VM??臻g夠不夠關系沒有直接關系,甚至是給每個線程的VM棧分配的內存越多反而越容易產生這個OOM異常。原因其實很好理解,操作系統分配給每個進程的內存是有限制的,譬如32位Windows限制為2G,Java堆和方法區(qū)的大小JVM有參數可以限制最大值,那剩余的內存為2G(操作系統限制)Xmx(最大堆)MaxPermSize(最大方法區(qū)),程序計數器消耗內存很小,可以忽略掉,那虛擬機進程本身耗費的內存不計算的話,剩下的內存就供每一個線程的VM棧和本地方法棧瓜分了,那自然每個線程中VM棧分配內存越多,就越容易把剩下的內存耗盡。清單3:創(chuàng)建線程導致OOM異常/*** VM Args:Xss2M(這時候不妨設大些)* @author zzm*/public class JavaVMStackOOM {private void dontStop() {while (true) {}}public void stackLeakByThread() {while (true) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {dontStop()。}})。()。}}public static void main(String[] args) throws Throwable {JavaVMStackOOM oom = new JavaVMStackOOM()。()。}}特別提示一下,如果讀者要運行上面這段代碼,記得要存盤當前工作,上述代碼執(zhí)行時有很大令操作系統卡死的風險。運行結果:Exception in thread main : unable to create new native thread運行時常量池要在常量池里添加內容,()這個Native方法。由于常量池分配在方法區(qū)內,我們只需要通過XX:PermSize和XX:MaxPermSize限制方法區(qū)大小即可限制常量池容量。實現代碼如下:清單4:運行時常量池導致的OOM異常/*** VM Args:XX:PermSize=10M XX:MaxPermSize=10M* @author zzm*/public class RuntimeConstantPoolOOM {public static void main(String[] args) {//使用List保持著常量池引用,壓制Full GC回收常量池行為ListString list = new ArrayListString()。// 10M的PermSize在integer范圍內足夠產生OOM了int i = 0。while (true) {((i++).intern())。}}}運行結果:Exception in thread main : PermGen spaceat (Native Method)at (:18)方法區(qū)上文講過,方法區(qū)用于存放Class相關信息,所以這個區(qū)域的測試我們借助CGLib直接操作字節(jié)碼動態(tài)生成大量的Class,值得注意的是,這里我們這個例子中模擬的場景其實經常會在實際應用中出現:當前很多主流框架,如Spring、Hibernate對類進行增強時,都會使用到CGLib這類字節(jié)碼技術,當增強的類越多,就需要越大的方法區(qū)用于保證動態(tài)生成的Class可以加載入內存。清單5:借助CGLib使得方法區(qū)出現OOM異常/*** VM Args:XX:PermSize=10M XX:MaxPermSize=10M* @author zzm*/public class JavaMethodAreaOOM {public static void main(String[] args) {while (true) {Enhancer enhancer = new Enhancer()。
點擊復制文檔內容
范文總結相關推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1