Suppose we have java task that is working in isolation and we are able to monitor it using visualvm... and we notice continuous garbage creation and periodic gc like this.
How do we detect what exactly is causing this issue
is there a way to see which method execution is generating garbage? how do we see where the garbage comes from?
yes we can see what objects exactly are allocating memory, but thats not helpful... i believe lot of objects are created and garbaged later, but i cant figure out where that happens and what exactly causes this...
How do we do this usually? what tools to use? any links to topics about this are appreciated
NOTE the problem here is not the GC parameter optimization, but rather the code optimization, we want to eliminate unnecessary object creation, maybe use primitives instead etc...
The easiest way is to use tool like JProfiler and record allocations. The "Allocation HotSpot" view will show in which method your application is allocating the objects. More details can be found here
When you cannot use profiler another approach is to take a heapdump and investigate the objects it contains. Then based on this information assume in which method they are instantiated.
I would suggest install VisualGC plugin in jvisualvm. It will give you very good idea about number of small and full GCs happening.
If you are looking for garbage collected objects and possible chance of memory leaks than you should inspect heap dump at two different instances of your code workflow.
Related
What is the easiest way to track down (i.e., find the cause of) a 'GC overhead limit exceeded' error?
What I do not consider good options:
Adding the -XX:-UseGCOverheadLimit parameter to the JVM call. That Java exception is telling me there is something incredibly inefficient in my implementation, and I want to fix that.
"Go and look carefully at your code". The project is very large, so I need some clues regarding where to look for inefficiencies.
Shoud I use a profiler? If yes, which one would you suggest?
Should I look into the GC log? I have tried doing that, but I have a little understanding of it, and it seems there are no clear pointers to the code (saying which objects are being GC'ed).
Many questions have been asked on SO about this error, but no one seems to answer this specific question.
Simplest tools to start profiling your app
Netbeans comes with a built in profiler.
Jconsole can also help a bit
VisualVm can also aid a bit.
Commercial Tools that is really awesome is DyanTrace
Now for the approach to fix your problem:
Although there can be other ways you can tackle it. but following things may help.
1) The symptoms that you are seeing are probably result of creation of too many short lived objects in your code. Now this is not a memory leak situation but too much garbage to clean for the JVM. And Jvm is failing to keep up with that. You need to check your code for where are these objects getting created.
2) Second thing you can do is take several heap dumps at regular intervals between two GC runs and compare these heapdumps in netbeans or some other tool of your choice. you need to do this before your app goes into this bad state.This comparison will tell you what has grown in heap and may be will give you a pointer where to look into your code.
I hope this helps in solving your issue. :)
I am looking for some ideas, and maybe already some concrete implemenatation if somebody knows any, but I am willing to code the wanted cache on my own.
I want to have a cache that caches only as many gigs as I configure. In comparision to the rest of the app the cache part will use nearly 100% of memory, so we can generalize the used memory of the app beeing the cache size(+ garbage).
Are there methods for getting a guess of how much memory is used? Or is it better to rely on soft pointers? Soft pointer and running always at the top of the jvm memory limit might be very inefficent with lots of cpu cycles for memory cleaning? Can I do some analysis on existing objects, like a myObject.getMemoryUsage()?
The LinkedHashMap has enough cache hits for my purpose so I don't have to code some strategic caching monster, but I don't know how to solve this momory issue properly. Any ideas? I don't want OOME flying anywhere.
What is best pratice?
SoftReference are not a great idea as they tend to be clearer all at once. This means when you get a performance hit from a GC, you also get a hit having to re-build your cache.
You can use Instrumentation.getObjectSize() to get the shallow size of an Object and use reflection to obtain a deep size. However, doing this relatively expensive and not something you want to get doing very often.
Why can't you limit the size to a number of object? In fact, I would start with the simplest cache you can and only add what you really need.
LRU cache in Java.
EDIT: One way to track how much memory you are using is to Serialize the value and store it as a byte[]. This can give you fairly precise control however can slow down your solution by up to 1000x times. (Nothing comes for free ;)
I would recommend using the Java Caching System. Though if you wanted to roll your own, I'm not aware of any way to get an objects size in memory. Your best bet would be to extend AbstractMap and wrap the values in SoftReferences. Then you could set the java heap size to the maximum size you wanted. Though, your implementation would also have to find and clean out stale data. It's probably easier just to use JCS.
The problem with SoftReferences is that they give more work to the garbage collector. Although it doesn't meet your requirements, HBase has a very interesting strategy in order to prevent the cache from contributing to the garbage collection pauses : they store the cache in native memory :
https://issues.apache.org/jira/browse/HBASE-4027
https://issues.apache.org/jira/secure/attachment/12488272/HBase-4027+%281%29.pdf
A good start for your use-case would be to store all your data on disk. It might seem naive, but thanks to the I/O cache, frequently accessed data will reside in memory. I highly recommend reading these architecture notes from the Varnish caching system :
https://www.varnish-cache.org/trac/wiki/ArchitectNotes
The best practice I find is to delegate the caching functionality outside of Java if possible. Java may be good in managing memory, but at dedicated caching system should be used for anything more than a simple LRU cache.
There is a large cost with GC when it kicks in.
EHCache is one of the more popular ones I know of. Java Caching System from another answer is good as well.
However, I generally offload that work to an underlying function (usually the JPA persistence layer by the application server, I let it get handled there so I don't have to deal with it on the application tier).
If you are caching other data such as web requests, http://hc.apache.org/httpclient-3.x/ is also another good candidate.
However, just remember you also have "a file system" there's absolutely nothing wrong with writing to the file system data you have retrieved. I've used the technique several times to fix out of memory errors due to improper use of ByteArrayOutputStreams
I've read in many threads that it is impossible to turn off garbage collection on Sun's JVM. However, for the purpose of our research project we need this feature. Can anybody recommend a JVM implementation which does not have garbage collection or which allows turning it off? Thank you.
I wanted to find a fast way to keep all objects in memory for a simple initial proof of concept.
The simple way to do this is to run the JVM with a heap that is so large that the GC never needs to run. Set the -Xmx and -Xms options to a large value, and turn on GC logging to confirm that the GC doesn't run for the duration of your test.
This will be quicker and more straightforward than modifying the JVM.
(In hindsight, this may not work. I vaguely recall seeing evidence that implied that the JVM does not always respect the -Xms setting, especially if it was really big. Still, this approach is worth trying before trying some much more difficult approach ... like modifying the JVM.)
Also, this whole thing strikes me as unnecessary (even counter-productive) for what you are actually trying to achieve. The GC won't throw away objects unless they are garbage. And if they are garbage, you won't be able to use them. And the performance of a system with GC disabled / negated is not going to indicative of how a real application will perform.
UPDATE - From Java 11 onwards, you have the much simpler option of using the Epsilon (no-op) garbage collector; see
JEP 318: Epsilon: A No-Op Garbage Collector (Experimental)
You add the following options when you launch the JVM:
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
When the heap is filled, no attempt is made to collect garbage. Instead, the Epsilon GC terminates the JVM.
Depending on your needs this could perhaps work:
Using the -Xbootclasspath option you may specify your own implementation of API classes. You could then for instance override the implementation of Object, and add to the constructor, a globalList.add(this) to prevent the objects from being garbage collected. It's a hack for sure, but for simple case-study it's perhaps sufficient.
Another option is to take an open source jvm and comment out the parts that initiate garbage collection. I would guess it is not that complicated.
Sun's JVM has no such option. AFAIK, no other JVM has this option either.
You did not state what it is that you are exactly trying to achieve but you have one of two options: either use a profiler and see exactly what the GC is doing, that way you can take its effects into consideration. The other is to compile one of the JVMs from source, and disable GC from there.
You can only turn off the GC if its not actually needed (otherwise your application would run out of memory) and if you didn't need to GC, it shouldn't run anyway.
The simplest option would be to not discard any objects, this will avoid GC being performed (And set the max memory very high so you don't run out).
You may find that you get GCs on startup and you may consider a no-GC when running acceptable.
the question is old but for those who might be interested, there is a proposal to
Develop a GC that only handles memory allocation, but does not implement any actual memory reclamation mechanism. Once available Java heap is exhausted, perform the orderly JVM shutdown.
JEP draft: Epsilon GC: The Arbitrarily Low Overhead Garbage (Non-)Collector
Maybe you could try making your VM's available memory sufficient for GC never to be run.
My (allbeit limited) experience leads me to suggest that the VM is, by default, extremely lazy and extremely reluctant to run GC.
giving -Xmx 16384M (or some such) and making sure that your research subject stays well below that limit, might give you the environment you wish to obtain, allthough even then it will obviously not be guaranteed.
There actually exists a dirty hack to temporarily pause GC. First create a dummy array in Java. Then, in JNI, use GetPrimitiveArrayCritical function to get hold of the pointer to the array. The Sun JVM will disable GC to ensure that the array is never moved and the pointer stays valid. To re-enable GC, you can call the ReleasePrimitiveArrayCritical function on the pointer. But this is very implementation specific since other VM impl may pin the object instead of disabling GC entirely. (Tested to work on Oracle Jdk 7 & 8)
Take a look at Oracle's JRockit JVM. I've seen very good near-deterministic performance on Intel hardware with this JVM and you can prod and poke the runtime using the Mission Control utility to see how well it's performing.
Though you can't turn GC off completely, I believe that you can use the -Xnoclassgc option to disable the collection of classes. The GC can be tuned to minimize latency at the expense of leaving memory consumption to grow. You may need a license to drop the latency as low as you need if you're going this route.
There is also a Realtime version of the JRockit JVM available but I don't think that there is a free-to-developers version of this available.
Can you get an open source JVM and disable its GC, for example Sun's Hotspot?
If there was no Garbage Collection what would you expect to be the semantics of code like this?
public myClass {
public void aMethod() {
String text = new String("xyz");
}
}
In the absence of GC any item newed and with a stack scoped reference could never be reclaimed. Even if your own classes could decide not to use local variables like this, or to use only primitive types I don't see how you would safely use any standard Java library.
I'd be interested to hear more about your usage scenario.
If I had this problem I would get IBM's Jikes Research Virtual Machine because:
The run-time system is written in Java itself (with special extensions)
The whole thing was designed as a research vehicle and is relatively easy to tweak.
You can't turn off GC forever, because Java programs do allocate and eventually you'll run out of memory, but it's quite possible that you can delay GC for the duration of your experiment by telling the JVM not to start collecting until the heap gets really big. (That trick might work on other JVMs as well, but I wouldn't know where to find the knobs to start twirling.)
I would like to run a Java program with garbage collection switched off. Managing memory in my own code is not so difficult.
However the program needs quite a lot of I/O.
Is there any way (short of using JNI for all I/O operations) that I could achieve this using pure Java?
Thanks
Daniel
What you are trying to achieve is frequently done in investment banking to develop low-latency real-time systems.
To avoid GC you simply need to make sure not to allocate memory after the startup and warm-up phase of your application.
As you seem to have noticed Java NIO internally does unwanted memory allocation.
Unfortunately, you have no choice but write JNI replacements for the problematic calls.
You need at least to write a replacement for the NIO Selector.
You will have to avoid using most of the Java libraries due to similar unwanted memory allocations.
For example you will have to avoid using immutable object like String, avoid Boxing, re-implement Collections that preallocate enough entries for the whole lifetime of your program.
Writing Java code this way is not easy, but certainly possible.
I am developing a platform to do just so.
Managing memory in my own code is not
so difficult.
It's not difficult - It's impossible. For example:
public void foo() {
Object o = new Object();
// free(o); // Doh! No "free" keyword in Java.
}
Without the aid of the garbage collector how can the memory consumed by o be reclaimed?
I'm assuming from your question that you might want to avoid the sporadic pauses caused by garbage collection due to the high level of I/O being performed by your app. If this is the case there are techniques for minimising the number of objects created (e.g. re-using objects from a pool). You could also consider enabling the Concurrent Mark Sweep Collector.
The concurrent mark sweep collector,
also known as the concurrent collector
or CMS, is targeted at applications
that are sensitive to garbage
collection pauses.
It's very hard (but not impossible) to disable GC in a JVM.
Look at the JNI "critical" functions for hints.
You can also essentially ensure you don't GC by not allocating any more objects (write a JVMTI agent that slaps you if you do, and instrument your code).
Finally, you can force a fatal OutOfMemoryError by ensuring that every object you allocate is never freed, thus when you hit -Xmx memory used, you'll fall over as GC won't be able to reclaim anything (mind you, you'll GC one or more times at this point before you fall over in a heap).
The real question is why you'd want to? What upside do you see in doing it? Is it for realtime? If so, I'd consider looking at one of the several realtime JVMs available on the market (Oracle, IBM, & others all sell them). I can't honestly think of another reason to do this while still using Java.
The only way you are going to be able to turn off garbage collection is to modify the JVM. This is should be feasible with OpenJDK 6 codebase.
However, the what you will get at the end is a JVM that leaks memory like crazy, with no reasonable hope of fixing the leaks. The Java class library APIs are designed and implemented on the assumption that there is a GC taking care of memory management. This is so fundamental that any serious attempt to "fix" it would lead to a language / library that is not recognizable as Java.
If you want a non-garbage collected language, use C or C++.
Modern JVM's are so good at handling short-lived objects that any scheme you devise on your own will be slower.
This is because the objects you handle yourself will become long-lived and receive extra deluxe treatment from the JVM in terms of being moved around etc. Of course, this is by the garbage collector, which you want to turn off, but you can do very little without any gc.
So, before you start considering what optimization to use, then establish a baseline where you have a large unoptimized, program and profile it. Then do your tweaks, and see if it helps, but you will never know if you do not have a baseline.
As other people have mentioned you can't disable the GC. However, you can choose to use the experimental 'Epsilon' garbage collector which will never actually perform any garbage collections. Warning: it will crash if your JVM runs out of memory (because it's not doing any garbage collections).
There's more info (including the command-line switch to use) at:
http://openjdk.java.net/jeps/318
Good luck!
GarbageCollection is automated memory management in java.So you can not disable GC
Since you say, "its all about predictability not straight line speed," you should look at using a realtime Java system with deterministic garbage collection.
The scheduler that runs as a daemon in JVM to garbage collect objects, can it be monitored with JMX.Do we have some way of telling that these are the objects it might garbage collect now.That way we can figure out that if we are creating specific objects of our classes and the instances are held up in memory of when they can be garbage collected and how much memory they take up.
Also is there a way of telling how much memory in average an instance of my class takes.
I know this question might be stupid but even though we cannot force garbage collection, can we find out at run time which objects are not being connected by other objects (in other word not being used at all).Can we find weak references at runtime, is there a way to depict that.
What you are asking about is called garbage collection tuning, and it has many resources in the web, such as this.
Specifically, there are application which you can use to monitor the behaviour of the memory of the java application such as VisualVM. You can also make the VM to print all the garbage collections to a file by adding the following flags to the commnad line:
-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
And then use analysis application such as gcviewer ot pmat to analyse them.
Use a profiler for this - take a look at Visual VM.