Java G1 垃圾收集器占用大量内存
Java G1 Garbage collector takes a lot of memory
我有一个大型数据库项目。为了解析它,我使用 java 和 G1 垃圾收集器。
当程序长时间运行时java开始消耗大量内存。
但是当我检查 java 堆时,大小要小得多。例如:
- Java 占用 20 Gb 内存
- "jmap -histo" - 告诉我堆大约有 5 Gb 的 RAM
问题:什么占用了我剩余的 RAM?这是G1的开销吗?
编辑:这是统计数据
java 进程:分配~50gb,消耗~20gb
jmap 信息:堆大小 ~4gb
RAM 消耗将是因为 巨大的数据库大小 和 结果集的大小 。
尝试以下操作:
优化垃圾收集:
警惕字符串连接运算符 (+),改用 concat()
如果使用spring,尝试setFetchSize(一次获取的行数)
然而,使用 setFetchSize 会增加你的执行时间,但它是内存高效的
删除所有不必要的语句
使用异步执行
我明白了这个问题。正如@Holger 提到的,ram 已分配给 java 进程,但未完全填满堆。但是原因为什么G1分配那么多ram:
如果 G1 需要分配大量巨大的区域,它就会受到影响。每次对象大小 > 区域大小的 50% 时都会创建它们。他们将浪费 space,因为该地区不会创建任何其他东西。因此,如果它的大小是 51%,您将浪费该区域的 49%。更糟糕的是,如果一个区域是 2MB,而你的对象是 2.1MB,它会在第二个区域浪费 1.9MB。如果分配大对象,请调整 XX:G1HeapRegionSize.
我有一个大型数据库项目。为了解析它,我使用 java 和 G1 垃圾收集器。 当程序长时间运行时java开始消耗大量内存。 但是当我检查 java 堆时,大小要小得多。例如:
- Java 占用 20 Gb 内存
- "jmap -histo" - 告诉我堆大约有 5 Gb 的 RAM
问题:什么占用了我剩余的 RAM?这是G1的开销吗?
编辑:这是统计数据
java 进程:分配~50gb,消耗~20gb
jmap 信息:堆大小 ~4gb
RAM 消耗将是因为 巨大的数据库大小 和 结果集的大小 。
尝试以下操作: 优化垃圾收集:
警惕字符串连接运算符 (+),改用 concat()
如果使用spring,尝试setFetchSize(一次获取的行数) 然而,使用 setFetchSize 会增加你的执行时间,但它是内存高效的
删除所有不必要的语句
使用异步执行
我明白了这个问题。正如@Holger 提到的,ram 已分配给 java 进程,但未完全填满堆。但是原因为什么G1分配那么多ram:
如果 G1 需要分配大量巨大的区域,它就会受到影响。每次对象大小 > 区域大小的 50% 时都会创建它们。他们将浪费 space,因为该地区不会创建任何其他东西。因此,如果它的大小是 51%,您将浪费该区域的 49%。更糟糕的是,如果一个区域是 2MB,而你的对象是 2.1MB,它会在第二个区域浪费 1.9MB。如果分配大对象,请调整 XX:G1HeapRegionSize.