pra*_*ams 5 java jvm memory-management
我将首先给出我们创建的对象的一些细节。并且会问一个问题(最后)。
我在 linux 上使用 64-but JVM。
我的 jvm 选项是:-Xmx6g -Xms3g -XX:MaxPermSize=256m
探查器 (jprofiler) 指出 2 个地方消耗大量内存:1) 这里每秒创建大约 4 个字符串(每个 110KB),并对每个字符串执行 StringUtils.replace。还执行了一些其他字符串分配等,但分析器清楚地表明 StringUtils.replace 是保存大部分内存的内容。2)在这里,每分钟创建一个包含 4 个对象(单个类)的对象(如果为 3.5MB,则保留大小)并(重新)放置到静态并发哈希图中(因此映射在任何时候都只包含 1 个对象)。父对象只有这 4 个子对象,没有别的。这 4 个对象中的每一个都包含 10K 个数组列表、10K 个日期和其他字符串等。我明确地将旧的父对象(我从 map.replace() 获得的那个)分配给 null 并明确地清除 (ArrayList.clear())数组列表,
内存行为是:内存使用量不断增加,并且一度发生主要收集(2GB)。次要收集 (700MB) 也大约每分钟发生一次。
问题:您是否认为 #1 实际上导致 eden 空间已满,因此 JVM 将 #2 中的对象推送到tenure 空间,因此内存使用量不断增加,直到发生主要收集?出于诊断目的,我将 #2 中的父对象更改为保留 500KB 的大小(小 7 倍,还有 1.4K 的 Date、ArrayList 等实例),但我仍然看到相同的内存行为。
我将选项更改为 -Xmx12g -Xms3g -XX:MaxPermSize=256m -XX:NewSize=8g 现在,我看到内存中 #2 中的对象数量较少,我看到保有权空间/老一代的增长较慢。现在可以快速收集 #2 中的那些对象,这很好,但是 CPU 使用率非常高,因为小收集现在很大(8G)并且每 2 分钟发生一次。
我的目标是快速收集所有对象(因此我没有看到内存使用量不断增加),但不会使次要集合太大。
关于我应该采取什么方法的任何建议?
收集伊甸园空间的成本与伊甸园空间中保留的对象数量成正比。由于成本较高,这表明很大一部分对象的保留时间超过 2 分钟。
当您每两分钟创建大约 6 GB 的对象(NewSize 包括两个幸存者空间),或每分钟大约 3 GB 时,其中大部分来自哪里,因为您建议的大小仅为每分钟几 MB。
我认为更好地了解 3 GB 的来源并减少它会很有用,因为看起来您每分钟只需要保留大约 10 MB。
顺便说一句:如果您每分钟创建 10 MB 的垃圾,则十小时内只会创建 6 GB,并且在此期间您不需要任何次要或主要的收集。
如果我跑
public class GCLikeMad {
public static void main(String... args) {
for(Long l = 0L; l < Integer.MAX_VALUE * 10L; l++);
}
}
Run Code Online (Sandbox Code Playgroud)
-XX:NewSize=256m我看到
[GC 295664K->240K(2121792K), 0.0011190 secs]
[GC 286832K->240K(2113216K), 0.0011510 secs]
[GC 278384K->240K(2105216K), 0.0012900 secs]
[GC 270256K->240K(2097280K), 0.0010110 secs]
[GC 262448K->240K(2257280K), 0.0013450 secs]
Run Code Online (Sandbox Code Playgroud)
-XX:newSize=8g -verbosegc我看到
[GC 6291664K->320K(7345408K), 0.0017790 secs]
[GC 6291776K->272K(7345408K), 0.0021570 secs]
[GC 6291728K->272K(7345408K), 0.0014490 secs]
[GC 6291728K->240K(8393600K), 0.0016680 secs]
[GC 8388080K->208K(8393600K), 0.0018730 secs]
Run Code Online (Sandbox Code Playgroud)
此时,使用-XX:NewSize=30g -mx31g -XX:SurvivorRatio=100 -verbosegc32 位引用并且仅使用一个 NUMA 内存区域。
[GC 30840864K->256K(31154304K), 0.0014270 secs]
[GC 30840832K->256K(31154304K), 0.0014730 secs]
[GC 30840832K->224K(31154304K), 0.0016500 secs]
[GC 30840800K->272K(31154304K), 0.0015740 secs]
[GC 30840848K->272K(31462336K), 0.0015280 secs]
Run Code Online (Sandbox Code Playgroud)
它-XX:NewSize=128g -mx130g -XX:SurvivorRatio=100 -verbosegc开始发挥作用。注意:此时正在使用多个 NUMA 内存区域和 64 位引用。每 2 分钟收集一次。
[GC 131586048K->320K(132907264K), 0.0042360 secs]
[GC 131586368K->1376K(132907264K), 0.0058030 secs]
[GC 131587424K->1440K(132907264K), 0.0034110 secs]
Run Code Online (Sandbox Code Playgroud)
此时,它仅用三个集合就创建了 200 亿个 Long 对象。
我想说 128 GB 的 Eden 空间是巨大的。:D
我的观点是增加 eden 大小并不会单独增加 GC 时间。保留的对象数量增加会增加所花费的时间。
| 归档时间: |
|
| 查看次数: |
1821 次 |
| 最近记录: |