日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

面试官上来就问:Java 进程中有哪些组件会占用内存?

發(fā)布時間:2025/3/21 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官上来就问:Java 进程中有哪些组件会占用内存? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文的內(nèi)容來自 StackOverflow 的一個問答:Java using much more memory than heap size (or size correctly Docker memory limit)

有網(wǎng)友留言,今天去參加面試,面試官上來就問:你能解釋為什么 Java 進(jìn)程占用內(nèi)存遠(yuǎn)超過堆內(nèi)存大小?如何正確計算 Docker 內(nèi)存限制?有沒有辦法減少 Java 進(jìn)程的堆外內(nèi)存(off-heap memeory)占用?

面對這類問題,這位網(wǎng)友是這樣答復(fù)的:

Java 進(jìn)程使用的虛擬內(nèi)存遠(yuǎn)遠(yuǎn)超過 Java 堆大小。要知道 JVM 包括許多子系統(tǒng),垃圾回收器、類裝載器、JIT 編譯器等等。所有這些子系統(tǒng)運行都需要占用內(nèi)存。JVM 不是內(nèi)存唯一的消費者,Java Class Library 在內(nèi)的所有 Native Library 也會占用內(nèi)存。對于內(nèi)存跟蹤工具來說這些開銷甚至無法跟蹤。Java 應(yīng)用程序本身還可以通過直接?ByteBuffers?使用堆外內(nèi)存。

這塊知識點其實需要包含很多個點,當(dāng)突如其來一個這類問題的時候,我們很難回答的很全面。在這里我們先系統(tǒng)的總結(jié)一下,如有遺留,請在文末留言。

1. 究竟 Java 進(jìn)程中有哪些組件會占用內(nèi)存?

通過 Native Memory Tracking 可以觀察到有以下 JVM 組件。

1.1 Java 堆

最顯而易見的就是 Java 堆,它是 Java 對象存在的地方。它會占用?-Xmx?參數(shù)指定大小的內(nèi)存。

1.2 垃圾回收器

GC 需要額外的內(nèi)存進(jìn)行堆管理,主要用于 GC 自身的結(jié)構(gòu)與算法。這些結(jié)構(gòu)包括 Mark Bitmap、Mark Stack(遍歷對象關(guān)系圖)、Remembered Set(記錄 region 之間引用)等等。其中一些可以直接調(diào)優(yōu),例如?-XX: MarkStackSizeMax?選項,另一些依賴于堆布局。其中 G1 region (-XX:G1HeapRegionSize)占用內(nèi)存較大,Remembered Set 占用內(nèi)存較小。

GC 的內(nèi)存開銷因算法而異,其中?-XX:+UseSerialGC?與?-XX:+UseShenandoahGC?的開銷最小,而 G1 或 CMS 則會輕松占用大約10%的堆內(nèi)存。

1.3 代碼緩存

代碼緩存包含動態(tài)生成的代碼,JIT 編譯生成的方法、解釋器以及運行時 stub 代碼。代碼大小受?-XX:ReservedCodeCacheSize?選項限制(默認(rèn)為240M)。關(guān)閉?-XX:-TieredCompilation?可以減少已編譯代碼的數(shù)量,從而減小代碼緩存。

1.4 編譯器

JIT 編譯器本身工作時也需要內(nèi)存。可以通過關(guān)閉 Tiered Compilation 或者?-XX:CICompilerCount?減少編譯使用的線程數(shù)。

1.5 類加載

類的元數(shù)據(jù)存儲在 Metaspace 堆外區(qū)域中,包括方法字節(jié)碼、符號、常量池、注解等。加載的類越多,使用的元數(shù)據(jù)就越多??梢酝ㄟ^?-XX:MaxMetaspaceSize(默認(rèn)無上限)和?-XX:CompressedClassSpaceSize(默認(rèn)1G)選項控制元數(shù)據(jù)總大小。

1.6 符號表

JVM 有兩個主要的 hashtable:符號表包含名稱、簽名、標(biāo)識符等,String 表包含對 interned String 引用。如果 Native Memory Tracking 顯示 String 表使用了大量內(nèi)存,這可能意味著應(yīng)用程序調(diào)用 String.intern 過于頻繁。

1.7 線程

線程堆棧也會申請內(nèi)存。堆棧大小由?-Xss?選項指定,默認(rèn)每個線程1M,幸運的是情況并非那么糟糕。操作系統(tǒng)會以延遲分配的方式分配內(nèi)存頁面,比如在第一次使用時分配,因此實際使用的內(nèi)存要低得多,通常每個線程堆棧占用80至200KB。我編寫了一個腳本評估有多少 RSS 屬于 Java 線程堆棧。

還有其他 JVM 部件會占用本地內(nèi)存,但它們在總內(nèi)存消耗中通常比例不大。

2. Direct Buffer

應(yīng)用程序可以通過 ByteBuffer.allocateDirect 調(diào)用直接請求非堆內(nèi)存。默認(rèn)的非堆內(nèi)存大小限制由?-Xmx?選項指定,但也可以使用?-XX:MaxDirectMemorySize?覆蓋配置。Direct ByteBuffer 包含在 Native Memory Tracking 輸出的 Other 區(qū)域,在 JDK 11 之前包含在 Internal 區(qū)域。

通過 JMX 可以在 JConsole 或 Java Mission Control 中直接看到 Direct Memory 的使用量:

除了 Direct ByteBuffer,還有?MappedByteBuffer?映射到進(jìn)程虛擬內(nèi)存中的文件。雖然 Native Memory Tracking 不對它跟蹤,但是?MappedByteBuffer?也會占用物理內(nèi)存,而且沒有一種簡單的方法限制它申請的內(nèi)存大小??梢酝ㄟ^查看進(jìn)程內(nèi)存映射了解實際的內(nèi)存使用情況:pmap-x <pid>。

Address???????????Kbytes????RSS????Dirty?Mode??Mapping ... 00007f2b3e557000???39592???32956???????0?r--s-?some-file-17405-Index.db 00007f2b40c01000???39600???33092???????0?r--s-?some-file-17404-Index.db^^^^^???????????????^^^^^^^^^^^^^^^^^^^^^^^^

3. Native Library

System.Loadlibrary?加載的 JNI 代碼可以不受 JVM 控制分配堆外內(nèi)存,標(biāo)準(zhǔn) Java Class Library 也是如此。尤其是未關(guān)閉的 Java 資源可能造成本地內(nèi)存泄漏。典型的例子是?ZipInputStream?和?DirectoryStream。

JVMTI 代理,尤其是 jdwp 調(diào)試代理,也會造成內(nèi)存消耗過多。

這個回答描述了如何使用 async-profiler 分析本地內(nèi)存分配。

4. Allocator 問題

進(jìn)程通常通過 mmap 系統(tǒng)調(diào)用直接從操作系統(tǒng)分配內(nèi)存,或者使用標(biāo)準(zhǔn)的 libc allocator —— malloc 分配本機(jī)內(nèi)存。反過來,malloc 會調(diào)用 mmap 向操作系統(tǒng)申請大塊內(nèi)存,然后根據(jù)自己的分配算法管理內(nèi)存塊。問題在于這種算法會造成碎片化以及過度使用虛擬內(nèi)存。

jemalloc 是 libc malloc 的一個更智能的替代選項,使用 jemalloc 占用內(nèi)存會變得更小。

5. 總結(jié)

因為有太多的因素需要考慮,沒有一種可靠的方法可以用來評估一個 Java 進(jìn)程所有的內(nèi)存使用量。

總內(nèi)存?=?堆?+?代碼緩存?+?Metaspace?+?符號表?+其他?JVM?結(jié)構(gòu)?+?線程堆棧?+Direct?Buffer?+?映射文件?+Native?Library?+?Malloc?開銷?+?...

雖然可以通過設(shè)置 JVM 參數(shù)縮小或限制類似代碼緩存這樣的區(qū)域,但是其他許多區(qū)域根本不受 JVM 控制。

設(shè)置 Docker 限制的一種可能的方法是觀察進(jìn)程“正常”狀態(tài)下的實際內(nèi)存使用情況。有一些工具和技術(shù)可以用來研究 Java 內(nèi)存消耗問題,Native Memory Tracking、pmap、jemalloc、async-profiler。

總結(jié)

以上是生活随笔為你收集整理的面试官上来就问:Java 进程中有哪些组件会占用内存?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲第一狼人区 | 亚洲影视精品 | 调教丰满的已婚少妇在线观看 | 8x8ⅹ成人永久免费视频 | 午夜一区二区三区免费 | 四虎影库永久在线 | 欧洲亚洲一区二区三区 | 黄色一机片 | 亚洲福利影院 | 操出白浆视频 | 黄色免费在线观看网站 | 操操操av | 亚洲成人av中文字幕 | 日本亚洲色大成网站www久久 | 国产思思| 中文字幕日韩国产 | 欧美青草视频 | 久久精品8| 他揉捏她两乳不停呻吟动态图 | 久久精品在线播放 | 日韩深夜福利 | 97夜夜操 | 激情国产视频 | 久久国产精品99久久人人澡 | 亚洲色成人一区二区三区小说 | 日韩精品在线观看中文字幕 | 久久综合伊人77777麻豆 | 欧美日在线 | 成人免费一区二区三区在线观看 | 九九热视频免费观看 | 在线观看理论片 | 成人深夜福利 | 日本视频黄 | 91麻豆精品国产91久久久无需广告 | 非洲黑人狂躁日本妞 | 极品超粉嫩尤物69xx | 少妇与公做了夜伦理 | 老头av| 免费一级片 | 亚洲一级片免费看 | 免费无遮挡网站 | 午夜精品一二三区 | 午夜免费福利视频 | 三级精品视频 | www.777含羞草 | 精品久久久久久久久久岛国gif | 欧美精品aaa | 国产视频1区 | 欧美一级免费观看 | 免费看av的网址 | 欧美日比视频 | av在线黄| 国内自拍在线 | 四虎久久 | 中文字幕在线观看播放 | 国产91久 | 国产精品二区一区二区aⅴ污介绍 | 日本a网| 成人精品一区二区三区视频 | 日韩av一区二区三区 | 精品国产乱码久久久 | 91微拍 | 自拍偷拍电影 | 欧美色乱 | 日本一区二区三区在线播放 | 黄色免费在线网站 | 国产夫妻性生活视频 | 国产精品无码人妻一区二区在线 | 午夜偷拍福利 | 黄色av网页| 91草视频 | 午夜精品免费 | 麻豆视频在线观看免费网站 | 福利毛片| youjizz国产| 校园春色亚洲 | a级黄色片免费看 | caoporn国产 | 91丨九色丨国产 | 香蕉视频在线观看视频 | 亚洲AV蜜桃永久无码精品性色 | 中文字幕一区二区三区久久久 | 欧美性猛交aaaa片黑人 | 欧美123区 | 99re国产精品| 2018自拍偷拍| 日韩中文字幕免费 | 中文字幕23页 | 日本成人在线免费观看 | 国产精品999久久久 在线青草 | 久久国产免费视频 | 黄色网av| 美女一二区 | 九九在线视频 | 俄罗斯色片 | 日韩午夜伦 | 日本美女日批视频 | 欧美呦交| 91超碰在线免费观看 |