摘要:概念對那些作用于不會逃逸出方法的對象,在分配內(nèi)存時,不在將對象分配在堆內(nèi)存中,而是將對象屬性打散后分配在線程私有棧內(nèi)存上,這樣隨著方法調(diào)用結(jié)束,棧上分配打散的對象也被回收掉,不在增加額外壓力。
概念
對那些作用于不會逃逸出方法的對象,在分配內(nèi)存時,不在將對象分配在堆內(nèi)存中,而是將對象屬性打散后分配在線程私有棧內(nèi)存上,這樣隨著方法調(diào)用結(jié)束,棧上分配打散的對象也被回收掉,不在增加 GC 額外壓力。
Java 對象分配流程 示例循環(huán)創(chuàng)建1000000000一個對象,阻止棧上分配
棧上分配條件:開啟逃逸分析 & 開啟標量替換
JVM 參數(shù):
棄用逃逸分析(不允許判斷對象是否可以逃逸出函數(shù)體)
-server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC
使用 server 模式棄用逃逸分析(-server -XX:-DoEscapeAnalysis),設(shè)置堆空間大小10m,初始空間10m,打印 GC 日志
棄用標量替換(不允許對象打散分配到棧上)
-server -Xmx10m -Xms10m -XX:+PrintGC -XX:-EliminateAllocations
以上二選一
代碼:
package com.mousycoder.mycode.happy_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-06-11 16:55 */ public class OnStackTest { public static class User{ public int id = 0; public String name = ""; } public static void alloc(){ User u = new User(); u.id = 5; u.name = "mousycoder"; } public static void main(String[] args) { long b = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { alloc(); } long e = System.currentTimeMillis(); System.out.println(e-b); } }
輸出:
[GC (Allocation Failure) 7651K->5603K(9728K), 0.0003680 secs] [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003829 secs] [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003809 secs] [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003731 secs] [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003286 secs]
VisualGC:
分析:
本次發(fā)生的是 Minor GC,發(fā)生 GC 的原因是堆空間沒有合適的區(qū)域能夠存放數(shù)據(jù)結(jié)構(gòu)導(dǎo)致的,堆從7651K 回收到 5603K,
感謝您的耐心閱讀,如果您發(fā)現(xiàn)文章中有一些沒表述清楚的,或者是不對的地方,請給我留言,您的鼓勵是作者寫作最大的動力。
作 者 : @mousycoder
原文出處 : http://mousycoder.com/thinking-in-jvm/7/
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75376.html
摘要:當一個對象被定義之后,可能會被外部對象引用,稱之為方法逃逸也有可能被其他線程所引用,稱之為線程逃逸。在編譯過程中,經(jīng)過逃逸分析確定一個對象不會被其他線程或者方法訪問,那么會將對象的創(chuàng)建替換成為多個成員變量的創(chuàng)建,稱之為標量替換。 1.引言 Java 程序運行時,JVM 會將 .class 字節(jié)碼轉(zhuǎn)換成機器能夠識別的指令,指令轉(zhuǎn)換過程會產(chǎn)生耗時,延緩程序的運行速度,為了解決這種問題出現(xiàn)了...
摘要:在一般應(yīng)用中,不會逃逸的局部對象所占的比例很大,如果能使用棧上分配,那大量的對象就會隨著方法的結(jié)束而自動銷毀了,垃圾收集系統(tǒng)的壓力將會小很多。相關(guān)參數(shù)設(shè)置大對象直接進入年老代的閾值,當對象大小超過這個值時,將直接在年老代分配。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級算法 GC策略的評價指標 JVM信息查看 GC通用日志解讀 jvm的card t...
摘要:虛擬機在執(zhí)行程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。棧幀棧幀是用于支持虛擬機進行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),它是虛擬機運行時數(shù)據(jù)區(qū)中的虛擬機棧的棧元素。棧幀的概念結(jié)構(gòu)如下運行時數(shù)據(jù)區(qū)腦圖高 這里我們先說句題外話,相信大家在面試中經(jīng)常被問到介紹Java內(nèi)存模型,我在面試別人時也會經(jīng)常問這個問題。但是,往往都會令我比較尷尬,我還話音未落,面試者就會背誦一段(Java虛擬...
摘要:解釋器與編譯器并存如果選用完全解釋策略,那么編譯器將停止所有的工作,字節(jié)碼將完全依靠解釋器逐行解釋執(zhí)行。如果選用完全編譯策略,那么解釋器仍然會在編譯器無法進行的特殊情況下介入運行,這主要是確保程序能夠最終順序執(zhí)行。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級算法 GC策略的評價指標 JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)...
閱讀 753·2023-04-25 20:32
閱讀 2360·2021-11-24 10:27
閱讀 4564·2021-09-29 09:47
閱讀 2278·2021-09-28 09:36
閱讀 3689·2021-09-22 15:27
閱讀 2800·2019-08-30 15:54
閱讀 398·2019-08-30 11:06
閱讀 1299·2019-08-30 10:58