xmx java_为什么我的Java进程比Xmx消耗更多的内存?
xmx java
你們有些人去過那里。 您已經在啟動腳本中添加了-Xmx選項,并放松了下來,因為您知道Java進程將不會消耗比經過微調的選項所允許的更多的內存。 然后,您感到非常討厭。 要么自己檢查開發/測試框中的過程表,要么事情真的變壞了,然后由操作人員在半夜打電話給您,告訴您您要生產的4G內存已用完。 而且該應用程序剛剛終止。
那么幕后到底發生了什么呢? 為什么進程消耗的內存比分配的更多? 是bug還是完全正常的東西? 忍受我,我將指導您進行到底。
首先,它的一部分肯定可以是內存泄漏的惡意本機代碼。 但是在99%的情況下,這完全是JVM的正常行為。 通過-Xmx開關指定的內容是限制應用程序堆消耗的內存。
除了堆以外,您的應用程序還使用內存中的其他區域,即permgen和堆棧大小。 因此,為了限制這些值,還應該分別指定-XX:MaxPermSize和-Xss選項。 簡而言之,您可以使用以下公式預測應用程序的內存使用情況
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]但是,除了您的應用程序占用的內存外,JVM本身還需要一些空間 。 對它的需求來自幾個不同的原因:
- 垃圾收集。 您可能還記得,Java是一種垃圾收集語言。 為了使垃圾收集器知道哪些對象適合進行收集,它需要跟蹤對象圖。 因此,這是內部簿記丟失的部分內存。 特別是G1以其對額外內存的過度需求而聞名,因此請注意這一點。
- JIT優化。 Java虛擬機在運行時優化代碼。 同樣,要知道要優化的部分,需要跟蹤某些代碼部分的執行情況。 同樣,您將失去記憶。
- 堆外分配。 如果您碰巧使用了堆外內存,例如,在自己使用直接或映射的ByteBuffer或通過一些聰明的第三方API時,那就瞧瞧-您正在將堆擴展到實際上無法通過JVM配置控制的范圍。
- JNI代碼。 例如,當您以2類數據庫驅動程序的格式使用本機代碼時,您將再次在本機內存中加載代碼。
- 元空間。 如果您是Java 8的較早采用者,那么您將使用元空間而不是舊的permgen來存儲類聲明。 這是無限的,并且在JVM的本機部分中。
除了上面列出的原因之外,您最終可能還會由于其他原因而使用內存,但是我希望我能說服您JVM內部消耗了大量內存。 但是,有沒有一種方法可以預測實際需要多少內存呢? 或者至少了解它消失的位置以便進行優化?
正如我們從痛苦的經歷中發現的那樣-無法以合理的精度進行預測。 JVM開銷的范圍從幾個百分點到幾百個百分點。 您最好的朋友還是古老的嘗試和錯誤。 因此,您需要以類似于生產環境和度量的負載運行應用程序。
衡量額外的開銷是微不足道的–只需使用OS內置工具(在Linux上排名靠前 ,在OS X上使用Activity Monitor ,在Windows上使用Task Manager )監視進程即可找出實際的內存消耗。 從實際消耗中減去堆大小和permgen大小,您將看到開銷。
現在,如果需要減少開銷,您想了解它實際消失的位置。 在這種情況下,我們發現Mac OS X上的vmmap和Linux上的pmap是真正有用的工具。 我們自己沒有使用vmmap端口連接Windows,但似乎也有Windows迷的工具。
以下示例說明了這種情況。 我使用以下啟動參數啟動了Jetty:
-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m知道我的應用程序中啟動了30個線程后,我可能會希望無論如何我的內存使用量都不會超過230M。 但是現在當我在Mac OS X上查看“ 活動監視器”時,會看到一些不同的東西。
實際內存使用量已超過320M。 現在,在vmmap <pid>輸出的幫助下, 深入了解該過程,我們開始了解內存在哪里消失。 讓我們看一些示例:
下面說我們丟失了將近2MB丟失到內存映射的rt.jar庫。
mapped file ???????????00000001178b9000-0000000117a88000 [ 1852K] r--/r-x SM=ALI ?/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/lib/rt.jar下一節說明,對于加載的特定動態庫,我們正在使用?6MB
__TEXT ????????????????0000000104573000-0000000104c00000 [ 6708K] r-x/rwx SM=COW ?/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/lib/server/libjvm.dylib在這里,我們沒有線程25-30,每個線程為其堆棧和堆棧防護分配1MB
Stack 000000011a5f1000-000000011a6f0000 [ 1020K] rw-/rwx SM=ZER thread 25 Stack 000000011aa8c000-000000011ab8b000 [ 1020K] rw-/rwx SM=ZER thread 27 Stack 000000011ab8f000-000000011ac8e000 [ 1020K] rw-/rwx SM=ZER thread 28 Stack 000000011ac92000-000000011ad91000 [ 1020K] rw-/rwx SM=ZER thread 29 Stack 000000011af0f000-000000011b00e000 [ 1020K] rw-/rwx SM=ZER thread 30STACK GUARD 000000011a5ed000-000000011a5ee000 [ 4K] ---/rwx SM=NUL stack guard for thread 25 STACK GUARD 000000011aa88000-000000011aa89000 [ 4K] ---/rwx SM=NUL stack guard for thread 27 STACK GUARD 000000011ab8b000-000000011ab8c000 [ 4K] ---/rwx SM=NUL stack guard for thread 28 STACK GUARD 000000011ac8e000-000000011ac8f000 [ 4K] ---/rwx SM=NUL stack guard for thread 29 STACK GUARD 000000011af0b000-000000011af0c000 [ 4K] ---/rwx SM=NUL stack guard for thread 30 我希望我能對預測和測量實際內存消耗這一棘手的任務有所了解。
翻譯自: https://www.javacodegeeks.com/2013/06/why-does-my-java-process-consume-more-memory-than-xmx.html
xmx java
總結
以上是生活随笔為你收集整理的xmx java_为什么我的Java进程比Xmx消耗更多的内存?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为 WATCH GT 4 手表上架预约
- 下一篇: Java 9:对Process API的