2016-09-15 134 views
2

答:如果我执行一个巨大的模拟程序-Xmx100000m(〜100GB),我看到堆中有一些尖峰(〜30GB)。这种尖峰增加了堆的大小,并减少了其他程序可以使用的内存。我想将堆大小限制为在没有内存异常的情况下运行程序所需的大小。最大堆大小xmx如何影响Java中的内存分配/使用堆?

enter image description here

B.如果我执行与-Xmx10000(10GB〜)我能够限制使用的堆大小(〜7 GB)我的模拟程序。总堆大小也是如此(当然)。在VisualVM数据中显示的程序的第一阶段(大约16分钟),我没有发现内存不足的情况。

enter image description here

我天真地预计,如果我增加XMX从10GB(B)到100GB(A),所使用的堆会维持不变和Java的只会为了避免出使用更多的内存内存异常。但是,这种行为似乎有所不同。我猜Java为了提高性能而以这种方式工作。

对A中大量使用堆的解释可能是如果xmx较大时散列映射的增长行为是不同的? xmx对负载因数有影响吗?

在程序中存在很多微型尖峰的阶段(例如参见B的12:06)而不是几个大的(A)处理一些java流。流处理的内存分配是否会自动适应xmx值? (还有一些内存可用于在B 12:06时减少微型尖峰)

如果不是,那么在A中使用较大的堆的原因是什么?

如何可能告诉Java如果可能(如在B的曲线中)那样保持已使用的堆低,但是如果可能发生内存不足异常(允许暂时切换到A)则需要更多的内存。这可以通过调整一些垃圾收集属性来完成吗?

编辑

如前所述由下面的答案,轮廓可以通过垃圾收集参数来改变。应用-Xmx100000m -XX:MaxGCPauseMillis = 1000调整A中的配置文件以消耗更少的内存(使用约20 GB)和更多时间(约22分钟)。

enter image description here

+0

我认为这与垃圾收集算法有关。每当GC发现有足够的空间可用时,它不会释放堆空间(以A为例)。但是,当GC发现该空间不足时,它会执行垃圾收集程序并以常规和短时间间隔(情况B)释放空间。 – KayV

回答

2

我想堆大小限制,实际上是要求无记忆的异常运行程序的大小。

你其实不愿意这样做,因为,因为只有提供等量的应用高峰足迹意味着当应用程序是附近最大的每一个分配将触发垃圾收集它会使你的程序非常缓慢。

我猜Java为了提高性能而以这种方式工作。

确实。

JVM有几个目标,按降序排列:

  • 暂停时间(潜伏期)
  • 分配吞吐量
  • 足迹

如果要优先于其他目标的足迹你必须放松其他的。