Basically we set an Initial heap memory and Maximum heap memory limit by setting -Xms and -Xmx parameters. I run the following program with -Xms set as 256MB and -Xmx set as 256 MB. But, when I run the following program, I expect an error "java.lang.OutOfMemoryError: Java heap space" since I am creating so many threadpools but never shutting down. But it doesn't happen. Instead it eats up all the RAM available and finally terminates without any error. And when I view the action through JConsole, I am not seeing any climb of both heap and non-heap memory beyond "Max". Can someone explain why it happens so? Where are the threadpool objects/threads created and why does Java doesn't consider memory params in this case.
Look at the method you are calling to create executor
It uses a LinkedBlockingQueue of Runnable - that queue is what you are adding to with execute( r1 ) - there is no limit to the size of this queue so your program just runs free adding more Runnables until it runs out of memory.
I expected the code to throw java.lang.OutOfMemoryError: Java heap space error after consuming 256MB of memory since I have set my heap memory to that value. But, it goes on and on till my RAM is exhausted completely. If my heap is not consumed for creating these objects then where are they getting created and how can I limit that memory reservation?
Maybe I'm missing something here, but one of the reasons for having resource pools is to be able to manage TOTAL number of resources. As far as I can see, the thread pool has a maximum of 5 threads available. Any attempt to obtain a 6th thread would bounce or be delayed. A quick RTFM says:
Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread. If the task cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been reached, the task is handled by the current RejectedExecutionHandler.
Since I don't see an override of the RejectedExecutionHandler, I'm going to have to assume that the default one just silently ignores the attempt. So you'd never reach OutOfMemory because only 5 threads would ever be actually running.
Customer surveys are for companies who didn't pay proper attention to begin with.
What's happening is that each call to startThreads creates a thread pool. Since the reference to the thread pool is in a member variable of TestObject1, the reference to the thread pool is released when the reference to TestObject1 is released. So, when the runnables in each thread pool complete, GC garbage collects your thread pool and releases the memory us by the thread pool. The program runs continuously without running out of memory
Try putting TestObject1 in a list, you will run out of memory eventually.