简体   繁体   中英

ExecutorService and OutOfMemoryError: unable to create new native thread while using Executor

I have a (java) web application base on JSP. In this application I can ask machines (PCs) about their state and actual operating system based on theirs IP by executing an external command.

To accelerate the request I thought to ask more machines simultaneously using threads, ie ExecutorService.

The preRenderView listener of the corresponding View is set to this method where I collect all the data that have to be shown. Here I initialize the executor, which is declared as a private static class field ( private static ExecutorService executor ):

public void selectData( ComponentSystemEvent event )
{
  AmtRoomMachinesListController.executor = Executors.newFixedThreadPool(20);

  AmtRoomMachinesListModel amtRoomMachinesListModel = (AmtRoomMachinesListModel)getModel();

  List< ListRow > listRows = fetchListRows( amtRoomMachinesListModel );
...
}

in fetchListRow the executor is called and the callable submitted. Then the executor is shut down and terminated:

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;
}

My problem is that the number of processes/threads increases constantly and after some time I get the OutOfMemory exception. Every time the selectData is called, the number of processes increases by the number of the prompted machines.

I'm a rookie with threading, but I thought that the executor would take care of the generated threads by terminating/killing them when executor.shutdown() or executor.awaitTermination or executor.purge() is called.

What am I missing?

Use one ThreadPool. Also, have you confirmed that awaitTermination function is returning true? It's a remote possibility that awaitTermination does not complete within 20 seconds and returns false. New thread pools keep getting created without the older ones getting GCed and eventually run out of memory.

My suggestion is to create only one thread pool. Thread pool is meant to manage your threads. If you are creating a thread pool everytime a method is called, then basically it is just as worse as creating thread everytime you are calling a method, but if you still insisted to create more than one thread pool then why don't you try this instead

private List< ListRow > fetchListRows( AmtRoomMachinesListModel amtRoomMachinesListModel )
{
   ExecutorService executor = Executors.newFixedThreadPool(20);
...
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;
}

just localized the executor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM