Spring Data JPA 元模型 JpaMetamodelMappingContext 内存消耗

7
我的Spring Data JPA/Hibernate应用程序在启动时消耗了超过2GB的内存,即使没有任何用户访问它。我使用Hazelcast作为二级缓存,但是当我使用ehCache时也遇到了同样的问题,所以这可能不是问题的原因。
我在Visual VM中运行了一个Heap Dump分析,发现JpaMetamodelMappingContext和大量的Map对象占用了大部分内存。我需要帮助理解我所看到的内容,以及这是否真的是一个问题。我的模型有一百个类,所以这可能是正常的,但我没有参考点。它似乎有点过度了。
一旦我有100个并发用户的负载,我的内存消耗就会增加到6-7 GB。考虑到我处理和缓存的数据量,这是相当正常的,但我觉得如果我能减少初始内存,我将有更多的增长空间。
请参见以下截图:Visual VM截图图片描述
1个回答

7
我认为你没有问题。相反,我认为你误解了你正在查看的数据。
请注意,堆空间图显示两个数字:堆大小已用堆 堆大小(橙色)是JVM可用于堆的内存量。这意味着它是JVM在某个时候从操作系统请求的数量。 已用堆是实际使用的堆大小部分。除了启动阶段之外,它会线性增长,然后反复下降。这是空闲应用程序的典型行为。应用程序的某些部分会生成适量的垃圾(曲线上升的部分),并不时进行收集。
该曲线的低点是您实际上正在使用的内存量。这似乎约为250MB,听起来不是很多,尤其是当您说实际工作时总共消耗6-7GB听起来合理时。
其他一些观察:
在启动时,CPU负载和堆快速增长/波动。因为此时正在分析库和实体,所以这是可以预期的。 JpaMetamodelMappingContext的保留大小约为23MB。再次,这是一个不小的内存块,但也并不是那么巨大。这包括它引用的东西,几乎全部是来自JPA实现的元数据,您可以在查看其源代码时轻松看到。

无论多长时间,它都是空闲的,使用率从未低于2GB内存。你会认为它会比这低得多。我没有在内存中存储任何东西,缓存寿命很短。 - chrislhardin
2
不确定你在说什么。每次GC循环时,使用量会降至250-300MB。 - Jens Schauder
在我的应用程序中,即使它长时间处于空闲状态,我也从未看到内存消耗降至2GB以下。 - chrislhardin
5
Jens想告诉你的是,你的应用程序在启动时从系统中预留了2GB的内存,因为他需要这么多。初始工作完成后,垃圾回收器会减少所需的内存,但JVM足够聪明,保留这2GB的内存,因为它可能在之后需要。从系统视角来看,JVM一直在使用这2GB的内存,但实际上只用了300MB。 - Zeromus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接