java - 防止java积极保留ram
问题描述
抱歉,如果问题已经存在,但无法找到。你能解释一下java内存使用的逻辑吗?有我的步骤:
- 设置 xmx4000M
- 运行应用
- 做压力测试
经过压力测试后,我的应用使用了大约 1.4G RAM。但是如果设置 xmx300M 并进行压力测试 - 没有性能跑题,但应用程序使用了大约 370M(我知道 xmx 是关于堆,gc 和其他东西也需要 ram)。为什么 java 如此积极地保留 ram,我可以阻止 java 这样做但留下高堆大小吗?
更新:我使用的 Java 16 OpenJDK 具有除 xml 之外的所有默认设置。PC 规格:i7 10700 16 GB 内存
解决方案
为什么java如此积极地保留ram。
GC 人体工程学。
如果 GC 有足够的可用空间,JVM 将使用更少的垃圾收集时间。因此,在调整堆大小时,它倾向于根据已用空间与可用空间的最佳比率来确定堆。
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 限制),当您的应用程序处于压力之下时,可能会降低吞吐量。
推荐阅读
- java - 在基于 Visual Studio Code Maven 的 Java 项目中设置类路径
- android - ROOM、SQLite 和类层次结构
- r - 通过匹配不同列的值创建组
- php - PHP动态表
- java - 通过 GarbageCollectorMXBean 确定 GC 类型
- php - 为什么关闭 Chrome 后没有保存 PHP Cookie 变量
- ios - .liquid shopify 主题导致 iOS 移动闪烁和页面重置
- azure - Azure 数据工厂 - 超出最大调用堆栈大小
- dart - Flutter:如何使用 JSON 加载所有分页数据
- fork - systemd 如何使用 Type=fork 跟踪 fork 进程