How to tell system threshold for Java Heap OutOfMemoryError?

B

BogusException

Situation: Program using lots of threads, communicating between them
with LinkedBlockingQueues.
Problem: Unbounded queue throws OutOfMemoryError. How to
anticipate/measure system capcity, and ultimately adjust queue sizes as
conditons on the server changes (to avoid throwing the excepton at
all).

Filling a Queue (LinkedBlockingQueue) with elements, I run into a
number of total elements in the queue where I throw a Heap error:
OutOfMemoryError. Once the queue (unbounded) reaches this heap limit,
it throws Java Heap OutOfMemoryError. The heap is used to track all
objects in memory, right? I thought RAM was used to store objects, and
heap was used to track each object in all threads.

This might not be a queue error at all, but merely a "too many objects
in all threads to keep track of" problem. Filling the queue with too
many elements might just trigger the condition.

Is there a way to anticipate the queue's capacity for objects, and thus
stop offer()-ing and direct element candidates elsewhere until the
queue's capacity increases? If the known system capacity for elements
in the queue were known, I could manage the queue capacity threshold
for each queue. The idea might be to anticipate the system's capacity
at runtime and configure a limit to the queue, instead of leaving it
unbounded.

In addition, I wonder if using a ConcurrentLinkedQueue might be more
robust than the LinkedBlockingQueue I'm using now. I can't seem to find
any performance comparisons or benchmarks.

TIA!

BogusException
 
V

Vincent van Beveren

An OutOfMemoryError is thrown when the maximum amount of memory assigned
to Java is used. It has nothing to do with the number of objects in a
particular thread or the number objects referenced, only the amount of
memory the total of all the objects use in the VM. You can set the
memory threshold with -Xmx and -Xms (execute 'java -X' for more
information).

To get the total amount of memory the VM can assign you can use the
following (somewhat complecated) code:

Runtime r = Runtime.getRuntime();
long usedMemory = r.totalMemory() - r.freeMemory();
long assignableMemory = r.maxMemory() - usedMemory;

The point is that the JVM increases its memory in steps... total memory
gives the total of the current step, but maxMemory gives the total
memory the JVM will try to use. This the above rather complecated
statement. You can run a thread that checks the assignable memory every
so-many-seconds. There are somewhat more advanced features in the
java.lang.management package which you can use if you want more control.
Check it out.

Vincent
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top