gpt4 book ai didi

java - FixedThreadPool 和 ExecutorCompletionService 的 OutOfMemory 错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:35:56 26 4
gpt4 key购买 nike

我正在开发应从数据库获取用户列表并从目录(ldap 或 AD)更新详细信息的应用程序。我在多核机器上做了什么这个过程所以我创建了这个应用程序(下面的代码)。我正在使用 CompletionService 并在 Future 对象中获取结果。

一段时间后,我遇到了“无法创建新的 native 线程”消息的内存不足错误。在任务管理器中,我看到该应用程序创建了大量线程,但我要求创建大小等于处理器数量的固定线程池。

我的代码有什么问题?

class CheckGroupMembership {
public static void main(String[] args) throws Exception {

final ExecutorService executor = Executors.newFixedThreadPool(**Runtime.getRuntime().availableProcessors()**);

CompletionService<LdapPerson> completionService =
new ExecutorCompletionService(executor)<LdapPerson>(executor);

final int limit = 2000;

DocumentService service1 = new DocumentService();
List<String> userNamesList = service1.getUsersListFromDB(limit);

List<LdapPerson> ldapPersonList = new ArrayList() <LdapPerson> (userNamesList.size());
LdapPerson person;

for (String userName : userNamesList) {
completionService.submit(new GetUsersDLTask(userName));
}

try {
for (int i = 0, n = userNamesList.size(); i < n; i++) {
Future<LdapPerson> f = completionService.take();
person = f.get();
ldapPersonList.add(person);
}
} catch (InterruptedException e) {

System.out.println("InterruptedException error:" + e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.exit(0);
}
}

ERROR CheckGroupMembership:85 - java.lang.OutOfMemoryError: unable to create new native thread java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: unable to create new native thread at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) at java.util.concurrent.FutureTask.get(FutureTask.java:83

GetuserDLs 任务

public class GetUsersDLTask implements Callable<LdapPerson> {
private String userName;

public GetUsersDLTask(String u) {
this.userName = u;
}

@Override
public LdapPerson call() throws Exception {
LdapService service = new LdapService();
return service.getUsersDLs(userName);
}

}

最佳答案

我很难相信您没有在 GetUsersDLTask 中创建线程(或者至少它是服务对象)。如果您查看堆栈跟踪,就会发现异常是从 Future 的 get() 方法中抛出的。设置此异常的唯一方法是在执行程序调用 Callabale.call() 之后。 call() 方法中发生的任何 throwable 都将在 Future 的内部 exception 字段中设置

例如:

Thread Pool: 
Thread-1
invoke call()
call()
Create Thread
throw OutOfMemoryError
propogate error to Thread pool
set exception

否则,当您向线程池提交请求时会发生此异常,而不是在您从 future 获取请求时发生。

关于java - FixedThreadPool 和 ExecutorCompletionService 的 OutOfMemory 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7919005/

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