调用OpenFGA的CompletableFuture方法致ForkJoinPool线程无法复用引发OOM
OpenFGA库引发ForkJoinPool线程泄漏导致OOM问题的原因与修复
问题现象
应用运行过程中创建了数千个ForkJoinPool线程池及线程,这些线程始终处于WAIT状态无法关闭,最终触发如下OOM错误(程序未崩溃):
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached // ...stacktrace [95433.690s][warning][os,thread] Failed to start thread "Unknown thread" - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached. [95433.691s][warning][os,thread] Failed to start the native thread for java.lang.Thread "pool-1917-thread-1" Caused by: java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
程序中仅OpenFGA库使用ForkJoinPool,核心调用代码如下:
// 业务调用代码 var response = fgaClient.listRelations(body, options).get(); // OpenFGA库中listRelations方法实现片段 public CompletableFuture<ClientListRelationsResponse> listRelations(ClientListRelationsRequest request, ClientListRelationsOptions listRelationsOptions) throws FgaInvalidParameterException { // 实现代码... return this.batchCheck(batchCheckRequests, options.asClientBatchCheckOptions()) .thenCompose(responses -> call(() -> ClientListRelationsResponse.fromBatchCheckResponses(responses))); }
问题原因
这是OpenFGA库的已知bug:在0.7.2版本之前,库内部的异步方法(如listRelations依赖的batchCheck等)每次调用时都会创建新的ForkJoinPool实例,且这些线程池没有被正确配置为可自动回收或手动关闭,导致线程池中的线程长期处于WAIT状态无法被JVM回收。随着调用次数增加,线程池和线程数量持续累积,最终耗尽系统的线程资源,触发“unable to create native thread”类型的OOM错误。
修复方案
直接将OpenFGA库升级到0.7.2及以上版本,该版本已修复线程池泄漏的问题,确保ForkJoinPool实例被合理复用或正确回收,避免无限制创建线程池和线程。
内容的提问来源于stack exchange,提问作者Minh Long Vu
相关产品推荐
相关产品推荐

