欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

教你JVM怎么使用native memory

 更新時(shí)間:2023年04月10日 09:46:40   作者:YocnZhao  
這篇文章主要為大家介紹了JVM怎么使用native memory原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

JRE如何使用native存儲(chǔ)

今天看到一篇特別好的文章,翻譯其中一小段Understanding how the JVM uses native memory

Runtime環(huán)境提供了被某些未知的用戶代碼驅(qū)動(dòng)的能力,這使runtime在任何情況下都能使用合適的資源。每一個(gè)JVM管理的java應(yīng)用的行為都會(huì)潛在的影響JVM所能提供的運(yùn)行時(shí)環(huán)境。這一節(jié)我們討論為什么Java應(yīng)用會(huì)消耗native存儲(chǔ)

Java堆和GC

Java的堆是用來存儲(chǔ)分配對(duì)象的一塊內(nèi)存,大多數(shù)的JVM有一塊邏輯堆內(nèi)存,也有少數(shù)的JVM實(shí)現(xiàn)了多塊堆存儲(chǔ)。一個(gè)物理內(nèi)存可以基于GC被分配成多塊邏輯上的內(nèi)存。

The Just-in-time (JIT) compiler

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

Classes and classloaders

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

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

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

JRE允許卸載class去回收空間,但是這僅僅是在內(nèi)存嚴(yán)重不足的情況下。不可能僅僅卸載一個(gè)單獨(dú)的class文件,而是卸載classloader,和它加載進(jìn)來的所有class,一個(gè)classloader僅僅會(huì)在以下情況下被卸載:

  • Java堆中不包含任何代表此classloader的java.lang.ClassLoader對(duì)象的應(yīng)引用
  • Java堆中不包含任何代表由此classloader加載進(jìn)來的類的java.lang.Class對(duì)象的引用
  • Java堆中沒有任何被此classloader加載進(jìn)來的對(duì)象存活。

JNI

JNI允許本地代碼和java代碼相互調(diào)用。JRE嚴(yán)重依賴JNI代碼去實(shí)現(xiàn)文件和網(wǎng)絡(luò)這些類庫的功能,一個(gè)JNI應(yīng)用能以三種方式增加JRE的native內(nèi)存

  • JNI應(yīng)用的native代碼會(huì)被編譯進(jìn)一個(gè)so動(dòng)態(tài)鏈接庫,運(yùn)行時(shí)會(huì)被加載到可執(zhí)行的地址空間呢,大型native應(yīng)用程序只需加載就可占據(jù)進(jìn)程地址空間的很大一部分。
  • native代碼必須跟JVM共享內(nèi)存,任何native代碼分配或者映射所需要的native內(nèi)存都需要占用JVM的內(nèi)存。
  • 某些JNI方法可以使用native作為他們正常操作的一部分,比如GetTypeArrayElements或者GetTypeArrayRegion方法都可以拷貝Java堆內(nèi)存到到native內(nèi)存供native代碼使用。以這種方式訪問大塊的Java堆內(nèi)存相應(yīng)的會(huì)占用大量的native內(nèi)存

NIO

NIO是java1.4之后添加的API,基于管道和緩存,以一種新的方式實(shí)現(xiàn)IO操作。除了基于堆的I/O,NIO還添加了基于native內(nèi)存的direct ByteBuffer(通過java.nio.ByteBuffer.allocateDirect()方法分配)。Direct ByteBuffers可以直接調(diào)用系統(tǒng)庫的方法去實(shí)現(xiàn)I/O操作,這會(huì)顯示提升在某些場(chǎng)景下的執(zhí)行效率,因?yàn)槟鼙苊庠贘ava堆和native堆之間拷貝數(shù)據(jù)。

我們可能會(huì)疑惑direct ByteBuffer申請(qǐng)的內(nèi)存到底存在哪里,應(yīng)用仍然用的是Java堆里面的對(duì)象去完成I/O操作,但是持有數(shù)據(jù)的緩存仍然存在native內(nèi)存中 -Java堆的對(duì)象只是持有了一個(gè)native堆緩存的引用。一個(gè)non-direct ByteBuffer則是直接在Java堆中存儲(chǔ)了byte[]數(shù)組。

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

Java堆發(fā)生GC的時(shí)候同樣會(huì)對(duì)Direct ByteBuffer數(shù)據(jù)執(zhí)行清除native緩存操作,GC僅僅會(huì)在Java堆中已經(jīng)滿了,不支持新的堆空間分配或者程序手動(dòng)調(diào)用GC(不建議手動(dòng)調(diào)用GC)的情況下發(fā)生。

還有一種情況,native內(nèi)存已經(jīng)滿了,又有代碼來請(qǐng)求native內(nèi)存,但是這個(gè)時(shí)候Java堆還沒有達(dá)到GC的條件,所以并不會(huì)發(fā)生GC。(也就是說native內(nèi)存的GC完全依賴Java堆的GC,反之如果native需要GC了但是堆沒有GC的需求的則不會(huì)引發(fā)GC)

Threads

應(yīng)用的每一個(gè)線程都需要內(nèi)存去儲(chǔ)存它的棧(這塊內(nèi)存用來存儲(chǔ)本地變量表和保存狀態(tài)),每一個(gè)Java線程都需要棧去執(zhí)行,根據(jù)實(shí)現(xiàn),Java線程可以具有單獨(dú)的native和Java棧。除了堆??臻g之外,每個(gè)線程還需要一些native內(nèi)存用于thread-local存儲(chǔ)和內(nèi)部數(shù)據(jù)結(jié)構(gòu)。
堆棧大小因Java實(shí)現(xiàn)和架構(gòu)而異。某些實(shí)現(xiàn)允許您指定Java線程的堆棧大小。通常在256KB和756KB之間的值。

盡管每個(gè)線程使用的內(nèi)存量非常小,但對(duì)于具有數(shù)百個(gè)線程的應(yīng)用程序,線程堆棧的總內(nèi)存使用量可能很大。運(yùn)行具有比可用處理器多的線程來運(yùn)行它們的應(yīng)用程序通常是低效的,并且可能導(dǎo)致性能低下以及增加的內(nèi)存使用。

以上就是教你JVM怎么使用native memory的詳細(xì)內(nèi)容,更多關(guān)于JVM使用native memory的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解idea切換git賬號(hào)的兩個(gè)方法

    詳解idea切換git賬號(hào)的兩個(gè)方法

    這篇文章主要介紹了詳解idea切換git賬號(hào)的兩個(gè)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 接口數(shù)據(jù)安全保證的10種方式

    接口數(shù)據(jù)安全保證的10種方式

    這篇文章主要為大家介紹了接口數(shù)據(jù)安全保證的10種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • VScode?隱藏大量無用的文件比如在看Linux?kernel或boot時(shí)候

    VScode?隱藏大量無用的文件比如在看Linux?kernel或boot時(shí)候

    這篇文章主要介紹了VScode?隱藏大量無用的文件比如在看Linux?kernel或boot時(shí)候,VScode 工程創(chuàng)建先在 Ubuntu 下編譯一下 uboot,然后將編譯后的 uboot 文件夾復(fù)制到 windows 下,并創(chuàng)建VScode 工程,需要的朋友可以參考下
    2022-10-10
  • 將Git存儲(chǔ)庫克隆到本地IntelliJ IDEA項(xiàng)目中的詳細(xì)教程

    將Git存儲(chǔ)庫克隆到本地IntelliJ IDEA項(xiàng)目中的詳細(xì)教程

    這篇文章主要介紹了將Git存儲(chǔ)庫克隆到本地IntelliJ IDEA項(xiàng)目中的詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 手把手教你將Vim改裝成一個(gè)IDE編程環(huán)境(圖文)  吳垠

    手把手教你將Vim改裝成一個(gè)IDE編程環(huán)境(圖文) 吳垠

    這篇文章主要介紹了手把手教你將Vim改裝成一個(gè)IDE編程環(huán)境(圖文) 吳垠 ,需要的朋友可以參考下
    2016-01-01
  • 分享VSCOCE遠(yuǎn)程連接服務(wù)器的一次錯(cuò)誤記錄(推薦)

    分享VSCOCE遠(yuǎn)程連接服務(wù)器的一次錯(cuò)誤記錄(推薦)

    這篇文章主要介紹了VSCOCE遠(yuǎn)程連接服務(wù)器的一次錯(cuò)誤記錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 如何使用?Merklized?抽象語法樹壓縮智能合約

    如何使用?Merklized?抽象語法樹壓縮智能合約

    Merklized?抽象語法樹?MAST(又名?Merklized?替代腳本樹)是一種使用?Merkle?樹壓縮比特幣智能合約的技術(shù),這篇文章主要介紹了使用?Merklized?抽象語法樹壓縮智能合約,需要的朋友可以參考下
    2023-12-12
  • git如何撤銷commit的方法(未push)

    git如何撤銷commit的方法(未push)

    這篇文章主要介紹了git如何撤銷commit的方法(未push),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Git里多種撤銷操作的最佳方法

    Git里多種撤銷操作的最佳方法

    這篇文章我們會(huì)給大家介紹關(guān)于Git里的多種撤銷操作,我會(huì)講解某些你需要“撤銷”已做出的修改的常見場(chǎng)景,以及利用 Git 進(jìn)行這些操作的最佳方法。下面來一起看看吧。
    2016-09-09
  • Postman返回中文亂碼的解決方案

    Postman返回中文亂碼的解決方案

    使用postman發(fā)出請(qǐng)求,返回值含有中文字符串,卻發(fā)現(xiàn)中文被亂碼,本文就詳細(xì)的介紹一下Postman返回亂碼的解決方案,感興趣的可以了解一下
    2022-01-01

最新評(píng)論