Java GC的容量约为2.5GB,尽管是-Xmx10G

Java GC的容量约为2.5GB,尽管是-Xmx10G,java,garbage-collection,jvm,Java,Garbage Collection,Jvm,我有一个关于大堆大小的Java垃圾收集的问题 当我使用64位JDK(java8u72)在64位windows上执行Java程序时: java-Xmx10G-Xms6G-verbose:gc 然后: java.exe内存利用率保持在2.5 GB左右(Windows任务管理器) 我每10-30秒获得一次GC,值大致相同:[GC(分配失败)2766094K->239630K(6647808K),0.0270937秒] 首先,这意味着什么?这2766094K在堆利用率之前(2.7G),然后是239

我有一个关于大堆大小的Java垃圾收集的问题

当我使用64位JDK(
java8u72
)在64位windows上执行Java程序时:

java-Xmx10G-Xms6G-verbose:gc
然后:

  • java.exe
    内存利用率保持在2.5 GB左右(Windows任务管理器)
  • 我每10-30秒获得一次GC,值大致相同:
    [GC(分配失败)2766094K->239630K(6647808K),0.0270937秒]
首先,这意味着什么?这2766094K在堆利用率之前(2.7G),然后是239630(2.3G),然后是6647808K(6G)是堆大小,对吗

当我要求最大堆容量为10GB时,为什么GC的容量大约为2.5G?如何解决这个问题

我的笔记本电脑有8GB的物理RAM,但我认为虚拟机的虚拟内存和transparant可以处理更大的堆大小


Tx

一个可能的原因可能是您试图分配一个大内存块(例如,一个大数组,可能通过
ArrayList
)。总的来说,有足够的可用空间不足以为大型阵列分配内存,可用空间还需要不间断(您需要一块完全可用且至少与阵列一样大的内存)


例如,如果您尝试创建一个大小为5的数组,并且在3、3和2的块中有可用内存,那么Java仍然需要执行GC,即使您总共有8个可用内存单元。

一个可能的原因可能是您试图分配一个大内存块(例如,一个大数组,可能通过
ArrayList
)。总的来说,有足够的可用空间不足以为大型阵列分配内存,可用空间还需要不间断(您需要一块完全可用且至少与阵列一样大的内存)

例如,如果您尝试创建一个大小为5的数组,并且在3、3和2的块中有可用内存,那么Java仍然需要执行GC,即使您总共有8个可用内存单元

  • 6647808K(6G)是年轻一代的堆大小。它不是实际的堆大小
  • 由于堆大小分为年轻一代和老一代,年轻一代和老一代之间的比例通常为1:8。因此,剩余的4GB分配给老一代。 JVM无法在young gen中分配内存,因此它启动了次要GC,因此young gen中的对象大小为2766094K,次要GC之后的内存大小为239630K 检查何时执行完全GC。如下图所示:

    [完全GC(元数据GC阈值)[PSYoungGen:11605K->0K(150016K)][ParOldGen:27075K->32787K(87040K)]38681K->32787K(237056K),[Metaspace:19481K->19481K(1067008K)],0.0989447秒][次:用户=0.33系统=0.00,实数=0.10秒]

  • 6647808K(6G)是年轻一代的堆大小。它不是实际的堆大小
  • 由于堆大小分为年轻一代和老一代,年轻一代和老一代之间的比例通常为1:8。因此,剩余的4GB分配给老一代。 JVM无法在young gen中分配内存,因此它启动了次要GC,因此young gen中的对象大小为2766094K,次要GC之后的内存大小为239630K 检查何时执行完全GC。如下图所示:


    [完全GC(元数据GC阈值)[PSYoungGen:11605K->0K(150016K)][ParOldGen:27075K->32787K(87040K)]38681K->32787K(237056K),[Metaspace:19481K->19481K(1067008K)],0.0989447秒][次:用户=0.33系统=0.00,实数=0.10秒]

    如果真的是10g,那么年轻一代就是GCed如果真的是10g,那么年轻一代就是GCed
    java -Xmx10G -Xms6G -verbose:gc <Class>