我将首先介绍我们创建的对象的一些细节。并会问一个问题(最终)。更小的伊甸园空间造成任期空间不断增加?
我在linux上使用64-JVM。
我的JVM选项有:-Xmx6g -Xms3g -XX:MaxPermSize参数=256米
探查(JProfiler的)表示2个地方消耗大量的内存:每秒 1)在此,约4字符串(每个110KB)被创建并且StringUtils.replace在每个字符串上执行。一些其他的字符串分配等也被执行,但分析器清楚地表明StringUtils.replace是持有大部分内存的东西。 2)在这里,每分钟创建一个包含4个对象(一个类的对象)的对象(保留大小为3.5MB),并(重新)放入一个静态的同步映射(因此映射只包含1个对象)。所有的父对象都有这4个子对象,没有别的。这4个对象中的每一个都包含10K数组列表,10K日期和其他字符串等。我明确指定旧的父对象(我从map.replace()获得的那个对象)为null并显式清除(ArrayList.clear())out这4个子对象内的ArrayList等。
内存行为是:内存使用量不断增加,并在一个主要集合(2GB)发生。次要收集(700MB)也每分钟发生一次。
问题:你认为#1实际上是导致eden空间满了,所以JVM会将#2中的对象推到任务空间,所以内存使用量不断增加,直到发生重大聚集?出于诊断目的,我将#2中的父对象更改为保留大小为500KB(较小7次,还有Date,ArrayList等的1.4K实例),并且我仍然看到相同的内存行为。
我将选项更改为-Xmx12g -Xms3g -XX:MaxPermSize = 256m -XX:NewSize = 8g现在,我在内存#2中看到较少的对象#我看到使用空间/旧创建的增长较慢。它的好处在于#2中的这些对象正在被快速收集,但CPU使用率非常高,因为现在很小的收集量(8G)并且每2分钟发生一次。
我的目标是快速收集所有对象(所以我没有看到内存使用量不断增加),但不会使次要收集过大。
我应该采取什么方法的任何建议?