中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM如何使用native?memory

發布時間:2023-05-08 16:16:58 來源:億速云 閱讀:202 作者:iii 欄目:開發技術

這篇“JVM如何使用native memory”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“JVM如何使用native memory”文章吧。

JRE如何使用native存儲

Runtime環境提供了被某些未知的用戶代碼驅動的能力,這使runtime在任何情況下都能使用合適的資源。每一個JVM管理的java應用的行為都會潛在的影響JVM所能提供的運行時環境。

Java堆和GC

Java的堆是用來存儲分配對象的一塊內存,大多數的JVM有一塊邏輯堆內存,也有少數的JVM實現了多塊堆存儲。一個物理內存可以基于GC被分配成多塊邏輯上的內存。

The Just-in-time (JIT) compiler

JIT編譯器會把java字節碼編譯成運行時可以直接運行的機器碼,這極大的提升了JRE運行速度,使Java代碼運行比肩native code。
字節碼編譯會使用native內存(同理,一些像GCC這樣的編譯器也需要內存去run),但是JIT的輸入(字節碼)輸出(機器碼)都必須存儲在native內存中。所以包含很多JIT-compiled的方法的應用相對來說更占用native內存。

Classes and classloaders

Java程序由定義了對象和方法邏輯的類組成,可能是Java運行時的庫(比如java.lang.String),也可能是三方庫。這些class在被使用的時候會被加載進來并被存儲在內存里面。

class如何被存儲不同JVM的實現相差極大。Sun JDK存儲在永生帶(PermGen),IBM從Java5開始為每個classloader開辟native內存并將它們存儲在那里。具體的存儲位置需要查看實現的文檔。

顯而易見的是,用更多的類會消耗更多的內存。(這意味著你的native內存消耗會持續增加,或者明確的開辟一塊內存,像PermGen,去容納所有的class),需要注意的是不止是你的應用的class需要存儲,frameworks,application servers,三方庫,JRE這里面的class在被用到的時候都會被加載并存儲進來。

JRE允許卸載class去回收空間,但是這僅僅是在內存嚴重不足的情況下。不可能僅僅卸載一個單獨的class文件,而是卸載classloader,和它加載進來的所有class,一個classloader僅僅會在以下情況下被卸載:

  • Java堆中不包含任何代表此classloader的java.lang.ClassLoader對象的應引用

  • Java堆中不包含任何代表由此classloader加載進來的類的java.lang.Class對象的引用

  • Java堆中沒有任何被此classloader加載進來的對象存活。

JNI

JNI允許本地代碼和java代碼相互調用。JRE嚴重依賴JNI代碼去實現文件和網絡這些類庫的功能,一個JNI應用能以三種方式增加JRE的native內存

  • JNI應用的native代碼會被編譯進一個so動態鏈接庫,運行時會被加載到可執行的地址空間呢,大型native應用程序只需加載就可占據進程地址空間的很大一部分。

  • native代碼必須跟JVM共享內存,任何native代碼分配或者映射所需要的native內存都需要占用JVM的內存。

  • 某些JNI方法可以使用native作為他們正常操作的一部分,比如GetTypeArrayElements或者GetTypeArrayRegion方法都可以拷貝Java堆內存到到native內存供native代碼使用。以這種方式訪問大塊的Java堆內存相應的會占用大量的native內存

NIO

NIO是java1.4之后添加的API,基于管道和緩存,以一種新的方式實現IO操作。除了基于堆的I/O,NIO還添加了基于native內存的direct ByteBuffer(通過java.nio.ByteBuffer.allocateDirect()方法分配)。Direct ByteBuffers可以直接調用系統庫的方法去實現I/O操作,這會顯示提升在某些場景下的執行效率,因為能避免在Java堆和native堆之間拷貝數據。

我們可能會疑惑direct ByteBuffer申請的內存到底存在哪里,應用仍然用的是Java堆里面的對象去完成I/O操作,但是持有數據的緩存仍然存在native內存中 -Java堆的對象只是持有了一個native堆緩存的引用。一個non-direct ByteBuffer則是直接在Java堆中存儲了byte[]數組。

JVM如何使用native?memory

Memory topology for direct and non-direct java.nio.ByteBuffers

Java堆發生GC的時候同樣會對Direct ByteBuffer數據執行清除native緩存操作,GC僅僅會在Java堆中已經滿了,不支持新的堆空間分配或者程序手動調用GC(不建議手動調用GC)的情況下發生。

還有一種情況,native內存已經滿了,又有代碼來請求native內存,但是這個時候Java堆還沒有達到GC的條件,所以并不會發生GC。(也就是說native內存的GC完全依賴Java堆的GC,反之如果native需要GC了但是堆沒有GC的需求的則不會引發GC)

Threads

應用的每一個線程都需要內存去儲存它的棧(這塊內存用來存儲本地變量表和保存狀態),每一個Java線程都需要棧去執行,根據實現,Java線程可以具有單獨的native和Java棧。除了堆棧空間之外,每個線程還需要一些native內存用于thread-local存儲和內部數據結構。
堆棧大小因Java實現和架構而異。某些實現允許您指定Java線程的堆棧大小。通常在256KB和756KB之間的值。

盡管每個線程使用的內存量非常小,但對于具有數百個線程的應用程序,線程堆棧的總內存使用量可能很大。運行具有比可用處理器多的線程來運行它們的應用程序通常是低效的,并且可能導致性能低下以及增加的內存使用。

以上就是關于“JVM如何使用native memory”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI

红桥区| 石景山区| 曲沃县| 赤壁市| 鄂州市| 咸丰县| 长葛市| 中阳县| 荥经县| 卢氏县| 元朗区| 马尔康县| 大冶市| 灌南县| 绵竹市| 漳州市| 松潘县| 镶黄旗| 佳木斯市| 吴川市| 昆明市| 六枝特区| 五峰| 吉隆县| 伊川县| 鄄城县| 从化市| 西林县| 江永县| 濉溪县| 南和县| 潼关县| 东莞市| 长岭县| 屯留县| 正阳县| 宁蒗| 肇州县| 咸丰县| 商都县| 利川市|