我尝试从 mongodb 获取一些数据,但我的 k8s pods 命中:
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 来保持这个大容量。
有人知道该批量大小是否可配置吗?
谢谢
根据您在评论中所说的,我认为您误诊了问题。批量大小(或您所说的“批量大小”)不是问题,更改 Mongo 驱动程序的内部批量大小并不能解决问题。真正的问题是,即使在过滤之后,您使用流创建的列表对于您正在使用的 Java 堆大小来说还是太大了。
有两种可能的方法来解决这个问题:
不是将注释放入 a List
,而是迭代流并在获得注释时处理它们。
想办法批量提取注解。然后获取每个批次中注释的单独列表。
(在其他情况下,我建议尝试在 MongoDB 查询本身中进行过滤。但这无助于解决您的 OOME 问题。)
但是,如果您需要同时处理内存中的所有注释,那么您唯一可行的选择就是获得更多内存。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句