Hello I am having a problem with the call to future.get() that never throws an OutOfMemoryError.
I needed to implement a timeout for some computations and did just like the accepted answer from this post suggests : How do I call some blocking method with a timeout in Java?
My code is the following:
int timeout = 1000;
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
@Override
public Integer call() {
/* Do some heavy computations that might use more memory than available */
return int;
}
};
int result = 0;
Future<Object> future = executor.submit(task);
try {
if (milliseconds > 0) {
result = (int) future.get(milliseconds, TimeUnit.MILLISECONDS);
} else {
result = (int) future.get();
}
} catch (TimeoutException ex) {
System.out.println("Timeout");
System.exit(1);
} catch (InterruptedException | ExecutionException e) {
System.out.println("Error");
System.exit(1);
} finally {
future.cancel(true);
executor.shutdown();
}
I would like to catch the OutOfMemoryError or at least crash the program, but currently, when using future.get(), the program never stops and when using future.get(timeout), the program stops only after timeout milliseconds, while the OutOfMemoryError usually happens long before the actual timeout.
In the second case, after the timeout, the logs are then
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "pool-1-thread-1"
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
What I would like to know is how to catch the OutOfMemoryError correctly to make sure the program does not idle when it will not produce anything useful anymore.
I also mention that for some reason the error got caught once when enclosing the /heavy computations/ within a try/catch, but when reexecuted a second time it did not work anymore.
I also add a screenshot of my taskmanager showing that java just idles while keeping the memory in use.