私は、dbからユーザーのリストを取得し、ディレクトリ(ldapまたはAD)から詳細を更新する必要があるアプリに取り組んでいます。マルチコアマシンでこの手順を実行するため、このアプリを作成しました(以下のコード)。CompletionService を使用して、Future オブジェクトで結果を取得しています。
しばらくすると、「新しいネイティブ スレッドを作成できません」というメッセージでメモリ不足エラーが発生します。タスクマネージャーで、アプリが大量のスレッドを作成したことがわかりますが、サイズがプロセッサの量に等しい固定スレッドプールを作成するように依頼しました。
コードの何が問題になっていますか?
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);
}
}
エラー CheckGroupMembership:85 - java.lang.OutOfMemoryError: 新しいネイティブ スレッドを作成できません java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: java.util.concurrent.FutureTask$Sync.innerGet で新しいネイティブ スレッドを作成できません( FutureTask.java:222) で 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);
}
}