How to monitor Java memory usage? - java

We have a j2ee application running on Jboss and we want to monitor its memory usage. Currently we use the following code
System.gc();
Runtime rt = Runtime.getRuntime();
long usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
logger.information(this, "memory usage" + usedMB);
This code works fine. That means it shows memory curve which corresponds to reality. When we create a big xml file from a DB a curve goes up, after the extraction is finished it goes down.
A consultant told us that calling gc() explicitly is wrong, "let jvm decide when to run gc". Basically his arguments were the same as disscussed here.
But I still don't understand:
how can I have my memory usage curve?
what is wrong with the explicit gc()? I don't care about small performance issues which can happen with explicit gc() and which I would estimate in 1-3%. What I need is memory and thread monitor which helps me in analysis of our system on customer site.

If you want to really look at what is going on in the VM memory you should use a good tool like VisualVM. This is Free Software and it's a great way to see what is going on.
Nothing is really "wrong" with explicit gc() calls. However, remember that when you call gc() you are "suggesting" that the garbage collector run. There is no guarantee that it will run at the exact time you run that command.

There are tools that let you monitor the VM's memory usage. The VM can expose memory statistics using JMX. You can also print GC statistics to see how the memory is performing over time.
Invoking System.gc() can harm the GC's performance because objects will be prematurely moved from the new to old generations, and weak references will be cleared prematurely. This can result in decreased memory efficiency, longer GC times, and decreased cache hits (for caches that use weak refs). I agree with your consultant: System.gc() is bad. I'd go as far as to disable it using the command line switch.

You can take a look at stagemonitor. It is a open source java (web) application performance monitor. It captures response time metrics, JVM metrics, request details (including a call stack captured by the request profiler) and more. The overhead is very low.
Optionally, you can use the great timeseries database graphite with it to store a long history of datapoints that you can look at with fancy dashboards.
Example:
Take a look at the project website to see screenshots, feature descriptions and documentation.
Note: I am the developer of stagemonitor

I would say that the consultant is right in the theory, and you are right in practice. As the saying goes:
In theory, theory and practice are the same. In practice, they are not.
The Java spec says that System.gc suggests to call garbage collection. In practice, it just spawns a thread and runs right away on the Sun JVM.
Although in theory you could be messing up some finely tuned JVM implementation of garbage collection, unless you are writing generic code intended to be deployed on any JVM out there, don't worry about it. If it works for you, do it.

Have you tried JMX?
http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html
(source: sun.com)

Peek into what is happening inside tomcat through Visual VM.
http://www.skill-guru.com/blog/2010/10/05/increasing-permgen-size-in-your-server/

Take a look at the JVM args: http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions
XX:-PrintGC Print messages at garbage collection. Manageable.
-XX:-PrintGCDetails Print more details at garbage collection.
Manageable. (Introduced in 1.4.0.)
-XX:-PrintGCTimeStamps Print timestamps at garbage collection.
Manageable (Introduced in 1.4.0.)
-XX:-PrintTenuringDistribution Print tenuring age information.
While you're not going to upset the JVM with explicit calls to System.gc() they may not have the effect you are expecting. To really understand what's going on with the memory in a JVM with read anything and everything the Brian Goetz writes.

Explicitly running System.gc() on a production system is a terrible idea. If the memory gets to any size at all, the entire system can freeze while a full GC is running. On a multi-gigabyte-sized server, this can easily be very noticeable, depending on how the jvm is configured, and how much headroom it has, etc etc - I've seen pauses of more than 30 seconds.
Another issue is that by explicitly calling GC you're not actually monitoring how the JVM is running the GC, you're actually altering it - depending on how you've configured the JVM, it's going to garbage collect when appropriate, and usually incrementally (It doesn't just run a full GC when it runs out of memory). What you'll be printing out will be nothing like what the JVM will do on it's own - for one thing you'll probably see fewer automatic / incremental GC's as you'll be clearing the memory manually.
As Nick Holt's post points out, options to print GC activity already exist as JVM flags.
You could have a thread that just prints out free and available at reasonable intervals, this will show you actual mem useage.

If you like a nice way to do this from the command line use jstat:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html
It gives raw information at configurable intervals which is very useful for logging and graphing purposes.

If you use java 1.5, you can look at ManagementFactory.getMemoryMXBean() which give you
numbers on all kinds of memory. heap and non-heap, perm-gen.
A good example can be found there
http://www.freshblurbs.com/explaining-java-lang-outofmemoryerror-permgen-space

If you use the JMX provided history of GC runs you can use the same before/after numbers, you just dont have to force a GC.
You just need to keep in mind that those GC runs (typically one for old and one for new generation) are not on regular intervalls, so you need to extract the starttime as well for plotting (or you plot against a sequence number, for most practical purposes that would be enough for plotting).
For example on Oracle HotSpot VM with ParNewGC, there is a JMX MBean called java.lang:type=GarbageCollector,name=PS Scavenge, it has a attribute LastGCInfo, it returns a CompositeData of the last YG scavenger run. It is recorded with duration, absolute startTime and memoryUsageBefore and memoryUsageAfter.
Just use a timer to read that attribute. Whenever a new startTime shows up you know that it describes a new GC event, you extract the memory information and keep polling for the next update. (Not sure if a AttributeChangeNotification somehow can be used.)
Tip: in your timer you might measure the distance to the last GC run, and if that is too long for the resulution of your plotting, you could invoke System.gc() conditionally. But I would not do that in a OLTP instance.

As has been suggested, try VisualVM to get a basic view.
You can also use Eclipse MAT, to do a more detailed memory analysis.
It's ok to do a System.gc() as long as you dont depend on it, for the correctness of your program.

The problem with system.gc, is that the JVM already automatically allocates time to the garbage collector based on memory usage.
However, if you are, for instance, working in a very memory limited condition, like a mobile device, System.gc allows you to manually allocate more time towards this garbage collection, but at the cost of cpu time (but, as you said, you aren't that concerned about performance issues of gc).
Best practice would probably be to only use it where you might be doing large amounts of deallocation (like flushing a large array).
All considered, since you are simply concerned about memory usage, feel free to call gc, or, better yet, see if it makes much of a memory difference in your case, and then decide.

About System.gc()… I just read in Oracle's documentation the following sentence here
The performance effect of explicit garbage collections can be measured by disabling them using the flag -XX:+DisableExplicitGC, which causes the VM to ignore calls to System.gc().
If your VM vendor and version supports that flag you can run your code with and without it and compare Performance.
Also note the previous quoted sentence is preceded by this one:
This can force a major collection to be done when it may not be necessary (for example, when a minor collection would suffice), and so in general should be avoided.

JavaMelody might be a solution for your need.
Developed for Java EE applications, this tool measure and build report about the real operation of your applications on any environments. It's free and open-source and easy to integrate into applications with some history, no database nor profiling, really lightweight.

Related

Should I call System.gc() in my java persistence project?

I'm using Java persistence API to develop a standalone software. Recently I saw that the memory usage keep rising when I'm creating objects from entity classes, as well as JPAController classes. It seems that the objects stays at the memory since the memory allocation to the project won't decrease (Eg: 400mb ---> Create Object ---> 450mb ---> Stays at 450mb). Will this affect badly on performance? Should I call System.gc() method to remove these objects?
Generally System.gc() is not guarenteed to perform a garbage collection. Ultimately it is up to the JVM to decide. See the javadoc.
Have you observed what happens when you are approaching your memory limits of the JVM, does garbage collection happen then ? If not and you receive an OutOfMemoryError, you either are retaining something longer than you need to, or actually need extra heap allocated to your VM.
In anycase System.gc() I believe shouldn't be used to solve such problems.
In my opinion, the approach to the problem should be different. Actually the call to System.gc() is not a guarantee that it will free any memory at all; please see When does System.gc() do anything
If you can measure a problem in your memory allocation, either via jconsole, or making a post mortem analysis on the jvm dump, or whatever, then this is another problem. By gathering this information you will know what remains where in your memory regions, and then take actions in order to contain it.
The only way that this would negatively affect performance throughout the life of your program is if you want to keep these entities around forever but the size of your old generation in your heap is less than the 450MB you specified. Assuming that you are want to keep around between 1 and 2 times the 450MB you have you have specified forever, with the default ratios of the JVM, setting a parameter such as -Xmx2g will probably be fine. There are many more parameters to fine tune your performance much more than that, but that's probably all the complexity you're looking for for now. If you want to check out some more details on heap tuning and really get into performance, check out this doc on Garbage Collection Tuning by Oracle. Alternatively, something to eat lunch to is a great Youtube video on GC tuning by a guy named Gil Tene.
But calling System.gc() probably won't do anything useful.

Importance of system.gc() in java [duplicate]

I know that garbage collection is automated in Java. But I understood that if you call System.gc() in your code that the JVM may or may not decide to perform garbage collection at that point. How does this work precisely? On what basis/parameters exactly does the JVM decide to do (or not do) a GC when it sees System.gc()?
Are there any examples in which case it's a good idea to put this in your code?
In practice, it usually decides to do a garbage collection. The answer varies depending on lots of factors, like which JVM you're running on, which mode it's in, and which garbage collection algorithm it's using.
I wouldn't depend on it in your code. If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it, because the garbage collector will attempt to free as much as it can before it goes to that extreme. The only time I've seen it used in practice is in IDEs where it's attached to a button that a user can click, but even there it's not terribly useful.
The only example I can think of where it makes sense to call System.gc() is when profiling an application to search for possible memory leaks. I believe the profilers call this method just before taking a memory snapshot.
You have no control over GC in java -- the VM decides. I've never run across a case where System.gc() is needed. Since a System.gc() call simply SUGGESTS that the VM do a garbage collection and it also does a FULL garbage collection (old and new generations in a multi-generational heap), then it can actually cause MORE cpu cycles to be consumed than necessary.
In some cases, it may make sense to suggest to the VM that it do a full collection NOW as you may know the application will be sitting idle for the next few minutes before heavy lifting occurs. For example, right after the initialization of a lot of temporary object during application startup (i.e., I just cached a TON of info, and I know I won't be getting much activity for a minute or so). Think of an IDE such as eclipse starting up -- it does a lot to initialize, so perhaps immediately after initialization it makes sense to do a full gc at that point.
The Java Language Specification does not guarantee that the JVM will start a GC when you call System.gc(). This is the reason of this "may or may not decide to do a GC at that point".
Now, if you look at OpenJDK source code, which is the backbone of Oracle JVM, you will see that a call to System.gc() does start a GC cycle. If you use another JVM, such as J9, you have to check their documentation to find out the answer. For instance, Azul's JVM has a garbage collector that runs continuously, so a call to System.gc() won't do anything
Some other answer mention starting a GC in JConsole or VisualVM. Basically, these tools make a remote call to System.gc().
Usually, you don't want to start a garbage collection cycle from your code, as it messes up with the semantics of your application. Your application does some business stuff, the JVM takes care of memory management. You should keep those concerns separated (don't make your application do some memory management, focus on business).
However, there are few cases where a call to System.gc() might be understandable. Consider, for example, microbenchmarks. No-one wants to have a GC cycle to happen in the middle of a microbenchmark. So you may trigger a GC cycle between each measurement to make sure every measurement starts with an empty heap.
You need to be very careful if you call System.gc(). Calling it can add unnecessary performance issues to your application, and it is not guaranteed to actually perform a collection. It is actually possible to disable explicit System.gc() via the java argument -XX:+DisableExplicitGC.
I'd highly recommend reading through the documents available at Java HotSpot Garbage Collection for more in depth details about garbage collection.
System.gc() is implemented by the VM, and what it does is implementation specific. The implementer could simply return and do nothing, for instance.
As for when to issue a manual collect, the only time when you may want to do this is when you abandon a large collection containing loads of smaller collections--a
Map<String,<LinkedList>> for instance--and you want to try and take the perf hit then and there, but for the most part, you shouldn't worry about it. The GC knows better than you--sadly--most of the time.
If you use direct memory buffers, the JVM doesn't run the GC for you even if you are running low on direct memory.
If you call ByteBuffer.allocateDirect() and you get an OutOfMemoryError you can find this call is fine after triggering a GC manually.
Most JVMs will kick off a GC (depending on the -XX:DiableExplicitGC and -XX:+ExplicitGCInvokesConcurrent switch). But the specification is just less well defined in order to allow better implementations later on.
The spec needs clarification: Bug #6668279: (spec) System.gc() should indicate that we don't recommend use and don't guarantee behaviour
Internally the gc method is used by RMI and NIO, and they require synchronous execution, which: this is currently in discussion:
Bug #5025281: Allow System.gc() to trigger concurrent (not stop-the-world) full collections
Garbage Collection is good in Java, if we are executing Software coded in java in Desktop/laptop/server. You can call System.gc() or Runtime.getRuntime().gc() in Java.
Just note that none of those calls are guaranteed to do anything. They are just a suggestion for the jvm to run the Garbage Collector. It's up the the JVM whether it runs the GC or not. So, short answer: we don't know when it runs. Longer answer: JVM would run gc if it has time for that.
I believe, the same applies for Android. However, this might slow down your system.
Normally, the VM would do a garbage collection automatically before throwing an OutOfMemoryException, so adding an explicit call shouldn't help except in that it perhaps moves the performance hit to an earlier moment in time.
However, I think I encountered a case where it might be relevant. I'm not sure though, as I have yet to test whether it has any effect:
When you memory-map a file, I believe the map() call throws an IOException when a large enough block of memory is not available. A garbage collection just before the map() file might help prevent that, I think. What do you think?
we can never force garbage collection. System.gc is only suggesting vm for garbage collection, however, really what time the mechanism runs, nobody knows, this is as stated by JSR specifications.
There is a LOT to be said in taking the time to test out the various garbage collection settings, but as was mentioned above it usually not useful to do so.
I am currently working on a project involving a memory-limited environment and a relatively large amounts of data--there are a few large pieces of data that push my environment to its limit, and even though I was able to bring memory usage down so that in theory it should work just fine, I would still get heap space errors---the verbose GC options showed me that it was trying to garbage collect, but to no avail. In the debugger, I could perform System.gc() and sure enough there would be "plenty" of memory available...not a lot of extra, but enough.
Consequently, The only time my application calls System.gc() is when it is about to enter the segment of code where large buffers necessary for processing the data will be allocated, and a test on the free memory available indicates that I'm not guaranteed to have it. In particular, I'm looking at a 1gb environment where at least 300mb is occupied by static data, with the bulk of the non-static data being execution-related except when the data being processed happens to be at least 100-200 MB at the source. It's all part of an automatic data conversion process, so the data all exists for relatively short periods of time in the long run.
Unfortunately, while information about the various options for tuning the garbage collector is available, it seems largely an experimental process and the lower level specifics needed to understand how to handle these specific situations are not easily obtained.
All of that being said, even though I am using System.gc(), I still continued to tune using command line parameters and managed to improve the overall processing time of my application by a relatively significant amount, despite being unable to get over the stumbling block posed by working with the larger blocks of data. That being said, System.gc() is a tool....a very unreliable tool, and if you are not careful with how you use it, you will wish that it didn't work more often than not.
If you want to know if your System.gc() is called, you can with the new Java 7 update 4 get notification when the JVM performs Garbage Collection.
I am not 100% sure that the GarbageCollectorMXBean class was introduces in Java 7 update 4 though, because I couldn't find it in the release notes, but I found the information in the javaperformancetuning.com site
I can't think of a specific example when it is good to run explicit GC.
In general, running explicit GC can actually cause more harm than good, because an explicit gc will trigger a full collection, which takes significantly longer as it goes through every object. If this explicit gc ends up being called repeatedly it could easily lead to a slow application as a lot of time is spent running full GCs.
Alternatively if going over the heap with a heap analyzer and you suspect a library component to be calling explicit GC's you can turn it off adding: gc=-XX:+DisableExplicitGC to the JVM parameters.
Accroding to Thinking in Java by Bruce Eckel, one use case for explicit System.gc() call is when you want to force finalization, i.e. the call to finalize method.
while system.gc works,it will stop the world:all respones are stopped so garbage collector can scan every object to check if it is needed deleted. if the application is a web project, all request are stopped until gc finishes,and this will cause your web project can not work in a monent.

How can I disable Java garbage collector?

We have a PHP webapp that calls a Java binary to produce a PDF report (with JasperReports). The Java binary outputs the PDF to standard output and exits; the PHP then sends the PDF to browser. This Java command lasts about 3 to 6 seconds, and I think when it lasts 6 second it's because the GC kicks in. I would like to disable the GC because anyway when the command exits all memory is returned.
I would like to know how to disable it for Java 1.4.2 and for Java 1.6.0 because we are currently testing both JVM to see which performs faster..
It sounds like you are trying to save time, but going about it the wrong way. The time saved in disabling garbage collection would be trivial (for a single task) compared to the time taken to launch and shutdown the java process. You might want to consider having a java process launch that you can ask multiple times to do the work you require if run-time performance is your goal.
There is no way to disable garbage collection entirely. Garbage collection is only run when the JVM runs out of space, so you could give the program more memory. Add these command line options to the Java command
-Xmx256M -Xms256M
This gives the program 256Mb of ram (the default is 64Mb). Garbage collection will not take 3 seconds for a default size JVM though, so you might want to investigate more closely what the program is doing. Yourkit profiler is very useful for figuring out what is taking a long time.
GC only kicks in when JVM is short on memory, so you either GC or die. Try turning on verbose GC and see if it actually takes significant amount of time.
java -verbose:gc
Java 11 comes with an no-op garbage collector.
It can be enabled by the -XX:+UseEpsilonGC option at JVM start.
According to the JEP decription one of its goals is to make certain short-lived jobs more efficient, what might be you use case:
Extremely short lived jobs. A short-lived job might rely on exiting quickly to free the resources (e.g. heap memory). In this case, accepting the GC cycle to futilely clean up the heap is a waste of time, because the heap would be freed on exit anyway. Note that the GC cycle might take a while, because it would depend on the amount of live data in the heap, which can be a lot.
Java 11 gives you the binary option to either have Java GC on, or have Java GC turned off. To turn off Java GC you use the Epsilon Garbage Collector which must be turned off on the command line. On Java 11, use the following two JVM arguments:
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
Without the UnlockExperimentalVMOptions argument, the JVM will fail to start, so make sure it's included.
Can't Stop Java GC
Unfortunately, if you're not using Epsilon GC, there is no way to disable, stop or prevent garbage collection from happening. Just like not being able to trigger GC, you can't stop Java GC either. The algorithms are non-deterministic. Only the JVM can control when they occur.
You can use the -Xmx option to set the maximum heap size; using a larger heap should prevent the VM from runnning out of memory and, thereby, requiring garbage collection so soon.
Are you sure that it is garbage collection causing the slowdown? Have you run java with -verbose:gc to see what is happening?
You cannot disable garbage collection on the JVM. You could however look at tuning the garbage collector for better performance.
Contrary to what everyone else has said, there is a way to suspend GC, though it's very convoluted.
If you call a native function via JNI, in between the native code calling GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical, GC is suspended. It has to do this because it is the mechanism used for sharing memory between Java and native code, and GC may move objects around in memory.
So to utilise this you'd need to create a JNI function which calls the former, then polls a flag written to that critical array (which could just be a byte[1]) waiting till it sees the flag before calling the latter. When the Java code wishes to suspend GC it would call the JNI method and when it wishes to resume GC, set the aforementioned flag (I believe reads/writes to the critical array are volatile, so the native code would see the flag immediately).
Now I'm not saying this is a good idea, and certainly not the correct solution to the OP's problem. But if you absolutely had to temporarily suspend GC for some reason (perhaps you wish to manipulate raw memory via sun.misc.Unsafe and needed to ensure objects were not moved about by GC whilst doing so), that's how you could achieve it.
As everyone as said you can't disable GC in the JVM, which makes sense right, because if you could there'd be memory leaks due to java not having an explicit way for the developer to delete the heap data.
Do you have access to the source of this java binary? If so it might be worth analysing it and seeing if there's any bottle-necks which could be better written to cut down on GC activity. This could be done with most java profilers, like JProbe for example.
To avoid garbage collector release a variable or property from any object,
you must set this property (released by gc) as static in your class
it was my solution.
Example:
private static String myProperty;

When to Garbage Collect

I have a piece of code that load a very big image in memory. So it seemed like a reasonable thing to call
System.gc();
before loading the image. From what I can tell it works with no issues.
Yesterday i decided to use a pretty useful piece of software called FindBugs that scans your code and reports back issues that might cause bugs or generally not advised strategies. The problem is that this piece of code i mentioned gets reported. The description is this:
... forces garbage collection;
extremely dubious except in
benchmarking code
And it goes on to elaborate :
Code explicitly invokes garbage
collection. Except for specific use in
benchmarking, this is very dubious.
In the past, situations where people
have explicitly invoked the garbage
collector in routines such as close or
finalize methods has led to huge
performance black holes. Garbage
collection can be expensive. Any
situation that forces hundreds or
thousands of garbage collections will
bring the machine to a crawl.
So my question is : Is it NOT OK to programmatically call the garbage collector in such a case? My code only calls it once and the method that it is in gets used rarely. And if it is not OK to call it then what should you do in a case where you need as much memory as possible before doing a very memory intensive operation and you need to free as much memory as posible prior to it?
Did you get any performance improvements with the System.gc()?
I don't think so, since you probably dont have a lot of objects that needs to be collected before you load the image.
Usually modern garbage collectors know best when to run, so you shouldnt force a collection, unless you have a really really good reason to. (for example a benchmarking application as suggested by that plugin)
btw: Calling System.gc() recommends the VM to perform a "full" or "large" collection, which means that all threads are stopped shortly.
Otherwise it will probably only make "small" garbage collections, which don't stop all threads.
Run your program with -verbose:gc to see how many bytes are collected.
There is also lots of technical information on garbage collection here:
http://java.sun.com/developer/technicalArticles/Programming/GCPortal/
Typically the GC is smarter than you, so it's better to let it run whenever the runtime decides. If the runtime needs memory, it'll run the GC itself
It's fine to call the garbage collector, you don't get any "problems" from it.
However, I doubt it will significently boost performance, unless that call also deals with defragging the allocated data. I don't know that.
What you should do in this case is profile the code. Run it several times, see what sort of results you get.
Typically, you should not interfere with the garbage collector. If it's necessary to free some memory before loading the image, then the garbage collector will do it for you.
Regardless, if you're only doing it once, it's probably not going to affect your performance drastically. Things done in loops are far more important.
You already got plenty of good advice, which I will try not to reiterate.
If you actually get problems with the GC, like full stops of your application for a second, do the following:
1. check that there aren't any calls to System.gc();
2. check out the various options for configuring the gc. There are tons of those around, and they are much more helpful, then forcing gc.
Ensure that the large objects can be gc'ed as early as possible. I.e. set variables to null and/or let them fall out of scope. THis helps!
If a memory allocation fails, a GC cycle is initiated and the allocation is tried again.
Generally, no. It isn't appropriate to call System.gc(). However, I have had a few cases where it made sense.
In the software I write, there is a built-in performance tracking layer. It is mostly used during automated testing, but can be used in the field for diagnostic purposes. Between tests or after specific runs we will call System.gc a few times and then record the memory still present. It provides us with a basic memory foot print benchmark for watching memory consumption trend lines over time. While this can be done with some of the external JVM interfaces, it was easier to do it in place and exact numbers were not required.
On a much older system, we could have upwards of 72 separate JVMs (yeah, 72, there was a good reason for it at the time of construction). In that system, leaving the heap to free float on all 72 JVMs could yield some excessive (well beyond physical memory) total memory consumption. System.gc() was called between heavy data exercises to try and keep the JVM closer to average to keep the heap from growing (capping the heap could have been another direction, but then it would have required the implementers to configure more per site and be more aware of what was happening under the hood to get it right and not have the system fail under load).

When does System.gc() do something?

I know that garbage collection is automated in Java. But I understood that if you call System.gc() in your code that the JVM may or may not decide to perform garbage collection at that point. How does this work precisely? On what basis/parameters exactly does the JVM decide to do (or not do) a GC when it sees System.gc()?
Are there any examples in which case it's a good idea to put this in your code?
In practice, it usually decides to do a garbage collection. The answer varies depending on lots of factors, like which JVM you're running on, which mode it's in, and which garbage collection algorithm it's using.
I wouldn't depend on it in your code. If the JVM is about to throw an OutOfMemoryError, calling System.gc() won't stop it, because the garbage collector will attempt to free as much as it can before it goes to that extreme. The only time I've seen it used in practice is in IDEs where it's attached to a button that a user can click, but even there it's not terribly useful.
The only example I can think of where it makes sense to call System.gc() is when profiling an application to search for possible memory leaks. I believe the profilers call this method just before taking a memory snapshot.
You have no control over GC in java -- the VM decides. I've never run across a case where System.gc() is needed. Since a System.gc() call simply SUGGESTS that the VM do a garbage collection and it also does a FULL garbage collection (old and new generations in a multi-generational heap), then it can actually cause MORE cpu cycles to be consumed than necessary.
In some cases, it may make sense to suggest to the VM that it do a full collection NOW as you may know the application will be sitting idle for the next few minutes before heavy lifting occurs. For example, right after the initialization of a lot of temporary object during application startup (i.e., I just cached a TON of info, and I know I won't be getting much activity for a minute or so). Think of an IDE such as eclipse starting up -- it does a lot to initialize, so perhaps immediately after initialization it makes sense to do a full gc at that point.
The Java Language Specification does not guarantee that the JVM will start a GC when you call System.gc(). This is the reason of this "may or may not decide to do a GC at that point".
Now, if you look at OpenJDK source code, which is the backbone of Oracle JVM, you will see that a call to System.gc() does start a GC cycle. If you use another JVM, such as J9, you have to check their documentation to find out the answer. For instance, Azul's JVM has a garbage collector that runs continuously, so a call to System.gc() won't do anything
Some other answer mention starting a GC in JConsole or VisualVM. Basically, these tools make a remote call to System.gc().
Usually, you don't want to start a garbage collection cycle from your code, as it messes up with the semantics of your application. Your application does some business stuff, the JVM takes care of memory management. You should keep those concerns separated (don't make your application do some memory management, focus on business).
However, there are few cases where a call to System.gc() might be understandable. Consider, for example, microbenchmarks. No-one wants to have a GC cycle to happen in the middle of a microbenchmark. So you may trigger a GC cycle between each measurement to make sure every measurement starts with an empty heap.
You need to be very careful if you call System.gc(). Calling it can add unnecessary performance issues to your application, and it is not guaranteed to actually perform a collection. It is actually possible to disable explicit System.gc() via the java argument -XX:+DisableExplicitGC.
I'd highly recommend reading through the documents available at Java HotSpot Garbage Collection for more in depth details about garbage collection.
System.gc() is implemented by the VM, and what it does is implementation specific. The implementer could simply return and do nothing, for instance.
As for when to issue a manual collect, the only time when you may want to do this is when you abandon a large collection containing loads of smaller collections--a
Map<String,<LinkedList>> for instance--and you want to try and take the perf hit then and there, but for the most part, you shouldn't worry about it. The GC knows better than you--sadly--most of the time.
If you use direct memory buffers, the JVM doesn't run the GC for you even if you are running low on direct memory.
If you call ByteBuffer.allocateDirect() and you get an OutOfMemoryError you can find this call is fine after triggering a GC manually.
Most JVMs will kick off a GC (depending on the -XX:DiableExplicitGC and -XX:+ExplicitGCInvokesConcurrent switch). But the specification is just less well defined in order to allow better implementations later on.
The spec needs clarification: Bug #6668279: (spec) System.gc() should indicate that we don't recommend use and don't guarantee behaviour
Internally the gc method is used by RMI and NIO, and they require synchronous execution, which: this is currently in discussion:
Bug #5025281: Allow System.gc() to trigger concurrent (not stop-the-world) full collections
Garbage Collection is good in Java, if we are executing Software coded in java in Desktop/laptop/server. You can call System.gc() or Runtime.getRuntime().gc() in Java.
Just note that none of those calls are guaranteed to do anything. They are just a suggestion for the jvm to run the Garbage Collector. It's up the the JVM whether it runs the GC or not. So, short answer: we don't know when it runs. Longer answer: JVM would run gc if it has time for that.
I believe, the same applies for Android. However, this might slow down your system.
Normally, the VM would do a garbage collection automatically before throwing an OutOfMemoryException, so adding an explicit call shouldn't help except in that it perhaps moves the performance hit to an earlier moment in time.
However, I think I encountered a case where it might be relevant. I'm not sure though, as I have yet to test whether it has any effect:
When you memory-map a file, I believe the map() call throws an IOException when a large enough block of memory is not available. A garbage collection just before the map() file might help prevent that, I think. What do you think?
we can never force garbage collection. System.gc is only suggesting vm for garbage collection, however, really what time the mechanism runs, nobody knows, this is as stated by JSR specifications.
There is a LOT to be said in taking the time to test out the various garbage collection settings, but as was mentioned above it usually not useful to do so.
I am currently working on a project involving a memory-limited environment and a relatively large amounts of data--there are a few large pieces of data that push my environment to its limit, and even though I was able to bring memory usage down so that in theory it should work just fine, I would still get heap space errors---the verbose GC options showed me that it was trying to garbage collect, but to no avail. In the debugger, I could perform System.gc() and sure enough there would be "plenty" of memory available...not a lot of extra, but enough.
Consequently, The only time my application calls System.gc() is when it is about to enter the segment of code where large buffers necessary for processing the data will be allocated, and a test on the free memory available indicates that I'm not guaranteed to have it. In particular, I'm looking at a 1gb environment where at least 300mb is occupied by static data, with the bulk of the non-static data being execution-related except when the data being processed happens to be at least 100-200 MB at the source. It's all part of an automatic data conversion process, so the data all exists for relatively short periods of time in the long run.
Unfortunately, while information about the various options for tuning the garbage collector is available, it seems largely an experimental process and the lower level specifics needed to understand how to handle these specific situations are not easily obtained.
All of that being said, even though I am using System.gc(), I still continued to tune using command line parameters and managed to improve the overall processing time of my application by a relatively significant amount, despite being unable to get over the stumbling block posed by working with the larger blocks of data. That being said, System.gc() is a tool....a very unreliable tool, and if you are not careful with how you use it, you will wish that it didn't work more often than not.
If you want to know if your System.gc() is called, you can with the new Java 7 update 4 get notification when the JVM performs Garbage Collection.
I am not 100% sure that the GarbageCollectorMXBean class was introduces in Java 7 update 4 though, because I couldn't find it in the release notes, but I found the information in the javaperformancetuning.com site
I can't think of a specific example when it is good to run explicit GC.
In general, running explicit GC can actually cause more harm than good, because an explicit gc will trigger a full collection, which takes significantly longer as it goes through every object. If this explicit gc ends up being called repeatedly it could easily lead to a slow application as a lot of time is spent running full GCs.
Alternatively if going over the heap with a heap analyzer and you suspect a library component to be calling explicit GC's you can turn it off adding: gc=-XX:+DisableExplicitGC to the JVM parameters.
Accroding to Thinking in Java by Bruce Eckel, one use case for explicit System.gc() call is when you want to force finalization, i.e. the call to finalize method.
while system.gc works,it will stop the world:all respones are stopped so garbage collector can scan every object to check if it is needed deleted. if the application is a web project, all request are stopped until gc finishes,and this will cause your web project can not work in a monent.

Categories

Resources