java threading memory management issues - java

I'm working on a program right now that is essentially this: there is a 4 way stop with cars arriving on each road at random times. Each road is served FCFS and the intersection is managed round robin style, 1 car crossing at a time. Each waiting car is a thread. I've gotten the thread synchronization and algorithm working no problem. The issue I can't quite figure out is how to prevent the error: OutOfMemoryError: unable to create new native thread. I realize that this is due to the heap (stack? I always get them switched) becoming full. I can't figure out a way to ensure executed threads are properly managed by the garbage collector and not lingering in memory after execution. I've tried setting my queues (each "road" with the car threads) up with soft references and nulling any hard references out to no avail. Anyone on here have experience with this!? THANKS!!!

"OutOfMemoryError: unable to create new native thread" does not refer to heap memory. It won't help you nulling references or using soft/weak references. Furthermore, increasing the heap size can only make things worse.
Java uses native memory for thread stacks. Each time you start a thread, a new stack is allocated, outside of the JVM heap. The stack is not released until the thread terminates. Consider using less concurrent threads (you can control the number by using ThreadPoolExecutor for example), or maybe decrease the stack sizes (using -Xss{size}k)
See also this post, which details many types of out of memory errors.

Did you tried using a ThreadPool?
You can create a ThreadPool since Java 5 in which you decide how many threads the Vm should initialize for you algorithm. Threads are created and reused.
I had a similar problem. Threads are not deleted/removed by the GarbageCollector and somehow live for ever.

This will only happen if you have too many running threads. (Not just references to threads) Like #Markus, I would suggest you switch to a ThreadPool like ExecutionService as it will manage the creation of threads and it works.
BTW: The concurrency library dates back to 1998, but was only included in Java 5.0 (2005) so if you have to have an older version you can use either the backport or the original library.

Related

Get memory usage of a thread

I know that I Java's Runtime object can report the JVM's memory usage. However, I need the memory usage for a certain thread. Any idea how to get this?
I appreciate your answer!
A Thread shares everything except its stack and the CPU cycles with all other threads in the VM. All objects created by the Thread are pooled with all the other objects.
The problem is to define what the memory usage of a Thread is. Is it only those objects it created? What if these objects subsequently are referenced by other threads? Do they only count half, then? What about objects created somewhere else, but are now referenced by this Thread?
I know of no tool trying to measure the memory consumption of separate Threads.

How to get the heap usage of a single thread at runtime within the same application?

I would like to measure the heap usage of a specific Thread from within the app that creates it.
That app is multi-threaded and has other threads that I am not interested in measuring.
Please do not point me at profilers or other external reporting tools. I am only interested in code I can run at runtime within the same application.
If possible I am looking to something similar to using ThreadMXBean to measure CPU time. If there is such a solution I have not found (and I have been searching for a while).
Also is there a way to know which memory pools a thread is using? I was thinking of using something similar to
HashSet<String> poolNames = getUsedPoolNames(thisThread);
long heapUsage = 0L;
for(MemoryPoolMXBean bean: ManagementFactory.getMemoryPoolMXBeans()) {
if(poolNames .contains(bean.getName()){
heapUsage += bean.getHeapUsage().getUsage().getUsed();
}
}
Would something like this work? What would getUsedPoolNames(~) look like?
How are memory pools and thread linked?
I don't think there's something at the API level that will get you that. Not easily, anyways. Memory's not really reserved against threads. Memory is reserved against objects, and objects are not thread-specific.
There is a nifty tool out there that can do all this by parsing memory dumps, but I'm not sure if it works against a live JVM.
What you would need to do is find the objects associated with the threead (not sure how to do that) and then navigate its references to calculate the retained heap (as the memory being used is more than just the the object itself, but also the objects whose references being held also take up memory. This is not a trivial task. And you're not going to get it from a simple API call. Plus, it's not really thread-specific, as another thread could have references to the same objects (as objects can be used by multiple threads.
Part of this is difficult because threads/objects are meant to be ignorant about the memory pools. That's something for the JVM to manage.
So, um, dunno.

What and how much overheads happen when I use a Reference class?

I saw there is a daemon thread running whenever we create a referenced object using any Reference class like
WeakReference,
FinalReference,
SoftReference,
PhantomReference,
Referemce
And if we have hierarchal thread structure then at each level there is an extra daemon thread initiated.
I would expect the overhead to be very small for most applications. Unless you know it is a problem I wouldn't worry about it. I have never seen references show up as an issue in a profiler and I have been using different profilers for 10 years.
The only way I see this becoming a problem is if your number of threads grows well into 2 digits and more.
Very roughly speaking:
10 threads will be next to unnoticeable
100 should be OK, since they're mostly just waiting and chewing up a bit of memory each
1000 will give your system a headache because those resources will be missing elsewhere
10000 will bring your system to its knees, if not outright kill it.

How to reclaim the memory used by a Java thread stack?

I've been having this memory leak issue for days and I think I have some clues now. The memory of my java process keeps growing but yet the heap does not increase. I was told that this is possible if I create many threads, because Java threads uses memory outside of the heap.
My java process is a server type program so there are 1000-2000 threads. Created and deleted ongoing. How do I reclaim the memory used by a java thread? Do I simply erase all references to the thread object and make sure that this is terminated?
Yes. That is the answer. As long as there is an active reference to any Java object, then that object won't be garbage collected when it's done.
If you're creating and destroying threads and not pooling them, I think you have other issues as well.
From the Java API docs threads die when:
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
Threads die when they return from their run() method. When they die they are candidates for garbage collection. You should make sure that your threads release all references to objects and exit the run() method.
I don't think that nulling references to your threads will really do the trick.
You should also check out the new threading facilities in Java 5 and up. Check the package java.util.concurrent in the API documentation here.
I also recommend you to check the book Concurrency in Practice. It's being priceless for me.
There are two things that will cause a Thread to be not garbage collected.
Any thread that is still alive will not be garbage collected. A thread is alive until the run method called by Thread.start() exits, either normally or by throwing an exception. Once this happens (and the thread's uncaught exception handler has finished), the thread is dead.
Any live reference to the Thread object for a thread will prevent it from being garbage collected. The live reference could be in your code, or if you are using thread pools, they could be part of the pool data structures.
The memory of my java process keeps growing but yet the heap does not increase.
That would be because each thread has a large (e.g. 1Mb) stack segment that is not allocated in the Java heap.
A thread's stack segment is only allocated when the thread is started, and released as soon as the thread terminates. The same also applies (I think) to the thread's thread-local map. A Thread object that is not "alive" doesn't use much memory at all.
So to sum it up. You appear to have lots of live threads. They won't be garbage collected as long as they are alive, and the only way to make them release their memory is to cause them to die ... somehow.
To reduce memory usage, you to need to do one or more of:
Look at the thread code (the run() methods, etc) to figure out why they are still hanging around.
Reduce the size of the thread stacks. (In theory, you can go as low as 64K ...)
Redesign your app so that it doesn't create thousands of threads. (Thread pools and some kind of work queue is one possible approach.)
That is a lot of threads, each of which imposes a memory overhead, and well as other resources for managing them (context switching etc). Use a profiler to view the thread activity - you'll likely find that most of the threads are idle most of the time.
I'd suggest the first step is to look at managing the threads using the thread pools provided by java.util.concurrent. Rather than creating threads, look to create tasks that are handed off to the pools. Tweak the pools until you have a much smaller number of threads that are kept reasonably busy. This may well resolve the memory issue; it will certainly improve performance.

how to get the memory used by a java process in java

I am running JBOSS server by deploying my own classes.Now i started doing some operations on my application.Now i would like to know the memory used by my application before and after performing operations.please support me in this regard
By using
MemoryMXBean
(retrieved by calling
ManagementFactory.getMemoryMXBean())
as well as
Runtime.getRuntime()'s methods:
.totalMemory(),
.maxMemory()
and
.freeMemory().
Note that this is not an exact art: while creating a new object, other temporary ones may be allocated, which will not give you an accurate measurement. As we know, java garbage collection is not guaranteed so you can't necessarily do that to eliminate dead objects.
If you research, you'll see that most code that attempts to do these measurements will have loops of Runtime.gc() calls and sleeps etc to try and ensure that the measurement is accurate. And this will only work on certain JVM implementations...
On an app server/deployed application, you will likely only get gross measurements/usage changes as the heap is allocated and the gc fires, but it should be enough. [I'm presuming that you wouldn't implement gc()'s and sleeps in production code :)]
Get the free memory before doing the operation Runtime.getRuntime().freeMemory() and then again after finishing the operation and you will get the memory used by your operation.
You may find the results you get are inconclusive. The GC will clean up used memory at random points in the background so you might find at if you run the same operations many times you will get different results. You can even appear to have more memory free after performing an operation.

Categories

Resources