gpt4 book ai didi

java - 'synchronized' 会影响流的内存占用吗?

转载 作者:行者123 更新时间:2023-12-01 12:11:15 25 4
gpt4 key购买 nike

我们有一个奇怪的 OutOfMemory(堆)案例。鉴于这种方法

private void processRemainingIds(final ITransaction tx) {
remainingIds.stream()//
.map(this::getInternalMessage)//
.filter(this::isMessageNeedsProcessing)//
.forEach(msg -> registerMessageAsMissing(msg, tx));
}

如果remainingIds 足够大,这个方法会相当稳定地填满堆。
  • getInternalMessage将加载“正常”大小的数据模型结构(即没有 blob/clob 等,只有几十个字符串和数字)
  • registerMessageAsMissing内部调用同步方法(可能是相关的)
  • 制作 getInternalMessage “同步”完全改变了内存行为,堆大小不再增加

  • 我希望上述实现会创建大量内部消息,检查并在需要时处理它们,然后丢弃每个对象并偶尔运行 GC。但这不是我们所看到的,而是我们得到的

    Growing heap

    OOM的标准问题,即。 “有东西捕获了你的物体”我很熟悉。但是为什么制作 getInternalMessage同步改变什么?

    最佳答案

    事实证明,更改为“同步”是一个转移注意力的问题,它既不是原因也不是解决方案。

    原因是 EclipseLink 的 UnitOfWork,它默认保存对每个加载实体的引用。如 getInternalMessage()正在加载许多对象,堆慢慢填满。解决方案是使用 ReferenceMode.FORCE_WEAK ,它只会创建对加载实体的弱引用,从而允许它们被 GC 处理。

    我推测制作 getInternalMessage() 同步 改变了执行,使得对象加载得更慢,可能会给 GC 多一点时间。这可能导致在同一时间段内内存倾斜较慢,但我们后来发现,使用 synchronized 也遇到了 OOM。

    关于java - 'synchronized' 会影响流的内存占用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58958433/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com