JSP (Java) 웹 응용 프로그램을 기반으로합니다. 이 응용 프로그램에서는 컴퓨터 (PC)에 외부 명령을 실행하여 IP 상태에 따라 상태 및 실제 운영 체제를 요청할 수 있습니다.ExecutorService 및 OutOfMemoryError : Executor를 사용하는 동안 새로운 네이티브 스레드를 만들 수 없습니다.
요청을 가속화하기 위해 더 많은 기계에 스레드 (예 : ExecutorService)를 동시에 요청하는 것으로 생각했습니다.
해당 View의 preRenderView 수신기는 표시해야하는 모든 데이터를 수집하는이 메서드로 설정됩니다. 여기에 개인 정적 클래스 필드 (private static ExecutorService executor
)로 선언 집행자를 초기화 :
fetchListRow
에
public void selectData(ComponentSystemEvent event)
{
AmtRoomMachinesListController.executor = Executors.newFixedThreadPool(20);
AmtRoomMachinesListModel amtRoomMachinesListModel = (AmtRoomMachinesListModel)getModel();
List<ListRow> listRows = fetchListRows(amtRoomMachinesListModel);
...
}
. 그런 다음 실행자는 종료하고 종료 :
private List<ListRow> fetchListRows(AmtRoomMachinesListModel amtRoomMachinesListModel)
{
...
List<ListRow> listRows = Collections.synchronizedList(new ArrayList<ListRow>());
for (Machine machine : room.getRoomPCs())
{
executor.submit(new AmtcWorker(listRows, machine, amtRoomMachinesListModel));
}
executor.shutdown();
try
{
executor.awaitTermination(20, TimeUnit.SECONDS);
}
catch (InterruptedException e)
{
throw new BootrobotException(ExceptionType.AMTC_ERROR, "command", "Waiting for thread termination", "error", e.getMessage());
}
((ThreadPoolExecutor)executor).purge();
LOGGER.info("Executor is shut down: " + executor.isShutdown());
LOGGER.info("Executor is terminated: " + executor.isTerminated());
sortListRows(listRows);
return listRows;
}
내 문제는 프로세스의 수/스레드가 지속적으로 증가하고 잠시 후 나는에서 OutOfMemory 예외를 얻을 수 있다는 것입니다. selectData
이 호출 될 때마다 프로세스 수는 프롬프트 된 시스템 수만큼 증가합니다.
나는 스레딩에 신참이지만 executor.shutdown() 또는 executor.awaitTermination 또는 executor.purge()가 호출 될 때 executor가 생성 된 스레드를 종료/종료하여 처리한다고 생각했습니다.
무엇이 누락 되었습니까?
현지화 의심이다. 하나의 실행 프로그램을 작성하여 모든 요청에 사용하는 것이 좋습니다. – OldCurmudgeon
실행자가 완료된 후에 참조를 null로 시도 했습니까? 그 외에, 나는 두 번째 @OldCurmudgeon. 하나의 "전역"ExecutorService를 만들고 [InvokeAll] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#invokeAll-java.util.Collection)을 사용해야합니다. -long-java.util.concurrent.TimeUnit-). – Fildor
코드에 로깅 문이 있습니다. 로그는 무엇을 보여줍니까? 잠깐 - 분명히,'executor'는 인스턴스 메소드에서 사용하는 클래스의'static' 변수입니다. 그것은 혼돈을 요구하고 있습니다. 이 변수는'selectData'가 호출 될 때마다 덮어 쓰여집니다. 다른 객체가 여전히 그것을 사용하고있다하더라도. 따라서 어떤 실행 프로그램을 종료할지 (또는 얼마나 자주), 종료하지 않을지에 대한 제어권이 없습니다. – Holger