【发布时间】:2021-06-17 21:41:33
【问题描述】:
我尝试从 mongodb 获取一些数据,但我的 k8s pod 命中:
Terminating due to java.lang.OutOfMemoryError: Java heap space
检查堆转储似乎会引起一些麻烦:
try (CloseableIterator<A> iter =
mongoTemplate.stream(query(criteria),
DocumentAnnotation.class,
ANNOTATIONS_COLLECTION_NAME)) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iter, Spliterator.ORDERED), false)
.filter(annotation -> isAnnotationAcceptedByFilter(annotation))
.collect(Collectors.toList());
}
一般来说,它使用 Mongo 驱动程序流 API 创建一个迭代器,并使用给定的标准迭代数据库返回的所有注释。似乎 Mongo DB 驱动程序正在读取 47427 项的批注(?至少我在堆转储中看到了),尽管事实上大多数都会被 Java 中的过滤器过滤,因此不会返回给客户端,这导致一个问题,因为每个这样的请求都会分配 100MB 的 RAM 来保持这个大容量。
有人知道批量大小是否可配置吗?
谢谢
【问题讨论】:
-
我想你可能误诊了。该大小的块大小应该没有问题。我怀疑真正的问题是您的过滤器没有过滤掉大部分项目(因此结果列表太大)或者其他地方存在内存泄漏。
-
但是这个问答是关于设置批量大小的:stackoverflow.com/questions/48072977
-
这似乎部分解释了这个问题:stackoverflow.com/questions/15516462/…,但仍然不清楚如何解决它......
-
我看不出它有什么关系。
-
嗯......那么......那是你的问题。如果过滤后的列表需要 500MB 来存储,那么您需要那么多内存。或者您需要更改您的应用程序设计/逻辑,以便您根本不需要创建列表。 (这与驱动程序使用的批量大小无关。)