hotspot 默认 gc_默认HotSpot最大直接内存大小
hotspot 默認 gc
在我以前的博客文章熱點選項中的Java 8改進的文檔 ,我寫的誤解圍繞熱點JVM非標準的默認設置選項 -XX:MaxDirectMemorySize 。 在本文中,我介紹了一種確定HotSpot JVM中“默認”最大直接內存大小的簡單方法。
Java啟動器的Java 8文檔對-XX:MaxDirectMemorySize聲明了以下內容(我強調了 ):
設置新I / O( java.nio程序包)直接緩沖區分配的最大總大小(以字節為單位)。 字母k或K表示千字節, m或M表示兆字節, g或G表示千兆字節。 默認情況下,大小設置為0,這意味著JVM會自動為NIO直接緩沖區分配選擇大小。
上面解釋了,如果沒有通過-XX:MaxDirectMemorySize選項明確指定大小,則HotSpot中最大直接內存大小的默認值為0 。 在這種情況下,使用-XX:+ PrintFlagsInitial和-XX:+ PrintFlagsFinal之類的選項無濟于事,因為當未明確指定時,這些值也將顯示為零。 例如,運行java -XX:+PrintFlagsFinal -version顯示:
size_t MaxDirectMemorySize = 0據我所知,沒有“標準”方式來訪問最大直接內存大小。 類java.lang.Runtime提供有關JVM中的近似可用內存,JVM中的總內存以及JVM將嘗試使用的最大內存的信息 。 盡管java.lang.management.MemoryMXBean除了提供堆內存使用之外還提供了非 堆內存使用 ,但是這種非堆使用是指“方法區域”,也可能是實現的“內部處理或優化”,而不是直接用于內存。
有一些非標準的方法來確定一個人的HotSpot JVM默認的最大內存大小。 在StackOverflow線程中, 有沒有一種方法可以測量Java中的直接內存使用情況? whiskeyspider撰寫了有關sun.misc.SharedSecrets.getJavaNioAccess()。getDirectBufferPool()。getMemoryUsed()?和sun.misc.VM.maxDirectMemory()的文章 。 這些特定于HotSpot的類分別指示正在使用的直接內存量和可以使用的最大直接內存量。
sun.misc.SharedSecrets類通過方法調用getJavaNioAccess().getDirectBufferPool()來訪問sun.misc.JavaNioAccess.BufferPool的實例,提供有關直接內存使用的信息。 BufferPool接口定義了三種提供直接內存相關詳細信息的方法: getCount() , getTotalCapacity()和getMemoryUsed() 。 盡管這些方法提供了有關直接內存使用的有趣信息,但它們并沒有告訴我們最大直接內存是多少。
HotSpot JVM中的sun.misc.VM.maxDirectMemory()方法為我們提供最大直接內存,無論它是使用-XX:MaxDirectMemorySize=顯式指定的,還是隱式設置為-XX:MaxDirectMemorySize=0 (默認值) VM選擇直接內存的最大大小。
為了幫助演示使用這些方法確定最大直接內存和使用的直接內存,我首先介紹一個將在示例中使用的實用程序。 這個enum被命名為MemoryUnit ,并且適用于ustin.utilities.memory.MemoryUnit.java中的這篇文章。 我本可以使用Apache Commons的FileUtils.byteCountToDisplaySize(long)或Brice McIver對其進行的更精細的修改 ,但決定使用這個簡單的TimeUnit – 啟發性的 enum ,如下所示。
MemoryUnit.java
package dustin.examples.maxdirectmemory;/*** Representation of basic memory units.*/ public enum MemoryUnit {/** Smallest memory unit. */BYTES,/** "One thousand" (1024) bytes. */KILOBYTES,/** "One million" (1024x1024) bytes. */MEGABYTES,/** "One billion" (1024x1024x1024) bytes. */GIGABYTES;/** Number of bytes in a kilobyte. */private final double BYTES_PER_KILOBYTE = 1024.0;/** Number of kilobytes in a megabyte. */private final double KILOBYTES_PER_MEGABYTE = 1024.0;/** Number of megabytes per gigabyte. */private final double MEGABYTES_PER_GIGABYTE = 1024.0;/*** Returns the number of bytes corresponding to the* provided input for a particular unit of memory.** @param input Number of units of memory.* @return Number of bytes corresponding to the provided* number of particular memory units.*/public double toBytes(final long input){double bytes;switch (this){case BYTES:bytes = input;break;case KILOBYTES:bytes = input * BYTES_PER_KILOBYTE;break;case MEGABYTES:bytes = input * BYTES_PER_KILOBYTE * KILOBYTES_PER_MEGABYTE;break;case GIGABYTES:bytes = input * BYTES_PER_KILOBYTE * KILOBYTES_PER_MEGABYTE * MEGABYTES_PER_GIGABYTE;break;default :throw new RuntimeException("No value '" + this + "' recognized for enum MemoryUnit.");}return bytes;}/*** Returns the number of kilobytes corresponding to the* provided input for a particular unit of memory.** @param input Number of units of memory.* @return Number of kilobytes corresponding to the provided* number of particular memory units.*/public double toKiloBytes(final long input){double kilobytes;switch (this){case BYTES:kilobytes = input / BYTES_PER_KILOBYTE;break;case KILOBYTES:kilobytes = input;break;case MEGABYTES:kilobytes = input * KILOBYTES_PER_MEGABYTE;break;case GIGABYTES:kilobytes = input * KILOBYTES_PER_MEGABYTE * MEGABYTES_PER_GIGABYTE;break;default:throw new RuntimeException("No value '" + this + "' recognized for enum MemoryUnit.");}return kilobytes;}/*** Returns the number of megabytes corresponding to the* provided input for a particular unit of memory.** @param input Number of units of memory.* @return Number of megabytes corresponding to the provided* number of particular memory units.*/public double toMegaBytes(final long input){double megabytes;switch (this){case BYTES:megabytes = input / BYTES_PER_KILOBYTE / KILOBYTES_PER_MEGABYTE;break;case KILOBYTES:megabytes = input / KILOBYTES_PER_MEGABYTE;break;case MEGABYTES:megabytes = input;break;case GIGABYTES:megabytes = input * MEGABYTES_PER_GIGABYTE;break;default:throw new RuntimeException("No value '" + this + "' recognized for enum MemoryUnit.");}return megabytes;}/*** Returns the number of gigabytes corresponding to the* provided input for a particular unit of memory.** @param input Number of units of memory.* @return Number of gigabytes corresponding to the provided* number of particular memory units.*/public double toGigaBytes(final long input){double gigabytes;switch (this){case BYTES:gigabytes = input / BYTES_PER_KILOBYTE / KILOBYTES_PER_MEGABYTE / MEGABYTES_PER_GIGABYTE;break;case KILOBYTES:gigabytes = input / KILOBYTES_PER_MEGABYTE / MEGABYTES_PER_GIGABYTE;break;case MEGABYTES:gigabytes = input / MEGABYTES_PER_GIGABYTE;break;case GIGABYTES:gigabytes = input;break;default:throw new RuntimeException("No value '" + this + "' recognized for enum MemoryUnit.");}return gigabytes;} }使用MemoryUnit作為幫助程序實用程序,下一個代碼示例演示如何使用SharedSecrets提供的JavaNioAccess.BufferPool上的方法。 這些值不是最大可能的直接內存,而是對已經使用的直接內存的估計。
/*** Write amount of direct memory used to standard output* using SharedSecrets, JavaNetAccess, the direct Buffer Pool,* and methods getMemoryUsed() and getTotalCapacity().*/ public static void writeUsedDirectMemoryToStdOut() {final double sharedSecretsMemoryUsed =MemoryUnit.BYTES.toMegaBytes(SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed());out.println("sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed(): "+ sharedSecretsMemoryUsed + " MB");final double sharedSecretsTotalCapacity =MemoryUnit.BYTES.toMegaBytes(SharedSecrets.getJavaNioAccess().getDirectBufferPool().getTotalCapacity());out.println("sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getTotalCapacity(): "+ sharedSecretsTotalCapacity + " MB"); }將類似以下內容的行放入直接存儲器后,即可執行以上代碼:
final ByteBuffer bytes = ByteBuffer.allocateDirect(1_000_000);如上所示使用直接內存并執行上面的代碼時,輸??出如下所示:
sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed(): 0.95367431640625 MB sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getTotalCapacity(): 0.95367431640625 MB剛剛演示的方法提供了使用的直接內存量的估計,但仍未顯示最大可用直接內存。 可以使用VM.maxDirectMemory確定,如下面的代碼清單所示。
/*** Write maximum direct memory size set (explicitly or* implicitly) for this VM instance using VM's* method maxDirectMemory().*/ public static void writeMaximumDirectMemorySizeToStdOut() {final double vmSize =MemoryUnit.BYTES.toMegaBytes(VM.maxDirectMemory());out.println("sun.misc.VM.maxDirectMemory(): " + vmSize + " MB"); }當以上代碼在我的筆記本電腦上使用JDK 8執行且未明確指定-XX:MaxDirectMemorySize ,結果如下所示:
sun.misc.VM.maxDirectMemory(): 1804.5 MB由此可見,我的機器上運行的JVM的默認最大直接內存大小約為1.8 GB。 我知道這是默認值,因為我沒有在命令行上顯式指定-XX:MaxDirectMemorySize ,并且因為使用-XX:+ PrintFlagsFinal運行示例Java應用程序時顯示為零(默認值)。
為了確保自己這種方法顯示的是正確的最大直接內存,我可以在命令行上顯式指定最大直接內存,并查看上面顯示的代碼寫了什么。 在這種情況下,我在命令行上提供-XX:MaxDirectMemorySize=3G 。 這是我使用顯式設置運行上述代碼時的輸出:
sun.misc.VM.maxDirectMemory(): 3072.0 MB結論
當需要知道可在HotSpot JVM上運行的特定應用程序使用的最大直接內存時 ,如果未明確指定-XX:MaxDirectMemorySize ,則方法VM.maxDirectMemory()可能是獲取此信息的最簡單方法。 當直接使用Java NIO時 ,甚至當使用Java NIO的產品(例如Terracotta和Hazelcast “ offheap”選項)間接使用Java NIO時,了解允許的最大直接內存將很有用。
翻譯自: https://www.javacodegeeks.com/2016/02/default-hotspot-maximum-direct-memory-size.html
hotspot 默認 gc
總結
以上是生活随笔為你收集整理的hotspot 默认 gc_默认HotSpot最大直接内存大小的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 炖蛋要多长时间 炖蛋要多长时间熟
- 下一篇: 民主是什么意思 民主怎么理解