首页 > 解决方案 > 防止java积极保留ram

问题描述

抱歉,如果问题已经存在,但无法找到。你能解释一下java内存使用的逻辑吗?有我的步骤:

  1. 设置 xmx4000M
  2. 运行应用
  3. 做压力测试

经过压力测试后,我的应用使用了大约 1.4G RAM。但是如果设置 xmx300M 并进行压力测试 - 没有性能跑题,但应用程序使用了大约 370M(我知道 xmx 是关于堆,gc 和其他东西也需要 ram)。为什么 java 如此积极地保留 ram,我可以阻止 java 这样做但留下高堆大小吗?

更新:我使用的 Java 16 OpenJDK 具有除 xml 之外的所有默认设置。PC 规格:i7 10700 16 GB 内存

标签: java

解决方案


为什么java如此积极地保留ram。

GC 人体工程学。

  1. 如果 GC 有足够的可用空间,JVM 将使用更少的垃圾收集时间。因此,在调整堆大小时,它倾向于根据已用空间与可用空间的最佳比率来确定堆。

  2. JVM 通常不愿意将内存还给操作系统。它通常只在一次major GC 之后执行此操作,并且只有在连续几次major GC 发现可用空间过多时才会这样做。(为什么?因为每次调整堆大小(向上或向下)都需要一次完整的 GC,而这很昂贵。)

堆比初始大小大得多的情况并不罕见,即使看起来堆比它需要的大。而且我们还知道应用程序的启动行为通常与其稳态行为有很大不同。(有很多 JVM 和应用程序“热身”效果。)

我可以阻止 java 这样做但留下高堆大小吗?

有些事情你可以调整。

  • 有一些 GC 选项可以让 GC 更愿意将内存还给操作系统。

  • 有(我认为)GC 选项会使 GC 不那么急于向操作系统请求更多内存。

但是这些东西会影响(通常)吞吐量;即它们会导致您的应用程序花费更多时间(更多 CPU 周期)运行垃圾收集器。

我的建议是阅读Oracle GC Tuning Guide开始。读完之后,回顾一下你的性能目标是什么,决定最合适的收集器,并尝试“基于行为的调优”方法。(这个想法是告诉 JVM 目标是什么,并让它自己设置低级 GC 调整参数以尝试实现它们。)

请记住,GC 调优是为了平衡成本与收益,并且最佳设置将根据应用程序及其(实际)工作负载而有所不同。


在您的情况下,我认为调整 GC 可能不值得。你说你有 16GB 的内存。该应用程序仅使用了 16GB 中的 1.6GB。这是压力测试......不是您的应用程序的正常操作。

现在,您可能正在针对 RAM 较少的生产环境进行优化。但如果是这种情况,建议您在生产平台本身上进行优化......或尽可能接近它。

另请注意,优化以停止 JVM 积极分配内存(达到 -Xmx 限制),当您的应用程序处于压力之下时,可能会降低吞吐量。


推荐阅读