Is it possible to force garbage collection in Java, even if it is tricky to do? I know about System.gc();
and Runtime.gc();
but they only suggest to do GC. How can I force GC?

- 6,313
- 15
- 32
- 40
-
32Perhaps it would be helpful to provide some background for why you need to force GC. Typically in a garbage collected language it is bad practice to explicitly call the collector. – Justin Ethier Sep 26 '09 at 13:18
-
3A given JVM may provide several garbage collection methods, each with its own advantages and disadvantages, and frequently a given situation can be avoided simply by hinting the JVM at startup time. Please elaborate on scenario. – Thorbjørn Ravn Andersen Sep 26 '09 at 17:17
-
I realise this question is 3 years old, but there is no accepted answer so i thought I'd add my 2 cents for anyone else. If you so desperately need garbage collection, then usually there's a way around. For example, calling string splits in a loop can cause massive memory usage. The trick is to know how to write code that addresses these limitations. Here is an excellent introductory site: http://iwillgetthatjobatgoogle.tumblr.com/post/12591334729/java-memory-leaks – aggregate1166877 Sep 12 '12 at 13:35
-
2Just as an add-on to the whole picture: System.gc() calls Runtime.gc(). Oracle documentation reports that the most proper way to invoke Runtime.gc() is through System.gc(), even though you're right, they merely suggest the JVM to run GC. As far as I know it is not possible to force the JVM to run GC, though you could use some coding technique to reduce memory (heap) waste. – Federico Zancan Apr 02 '13 at 10:10
-
3jmap -histo:live
http://stackoverflow.com/questions/6418089/does-jmap-force-garbage-collection-when-the-live-option-is-used – Jun 07 '13 at 14:36 -
9Here's a use case for forcing garbage collection: I have a server with a 30GB heap, of which ~12GB is typically used (~5M objects). Every 5 minutes, the server spends roughly one minute performing a complex task in which roughly 35M additional objects are used. A full GC is triggered a couple of times per hour, invariably during the complex task, and freezes the VM for 10 to 15 seconds. I would love to force the full GC to run at a time when the complex task is not running; it would then be juggling 5M live objects rather than 40M. – Steve Oct 16 '13 at 20:21
-
5@JustinEthier There is one pretty obvious case where you may want to force the GC, which is unit testing any behaviour involving the java.lang.ref.Reference type hierarchy. – Elias Vasylenko Oct 05 '16 at 18:33
-
Another case requiring garbage collection: unloading native dlls reliably. – UKMonkey Jan 10 '17 at 12:58
-
1@JustinEthier benchmarking – Jason Lee Mar 15 '19 at 02:30
-
Profiling tools like JProfiler seems to be capable of triggering immediate garbage collection. – Jaime Hablutzel May 26 '20 at 18:18
25 Answers
Your best option is to call System.gc()
which simply is a hint to the garbage collector that you want it to do a collection. There is no way to force and immediate collection though as the garbage collector is non-deterministic.

- 5,568
- 2
- 35
- 47

- 344,730
- 71
- 640
- 635
-
44
-
12A garbage collector may be non-deterministic and still offer a way to force an immediate collection. For example, usually the .NET collector is non-deterministic but a call to GC.Collect() forces it run. It's just that Java chooses not to expose this function. – Petr Hudeček Jan 12 '15 at 08:07
-
2In my experience, this method always invokes the garbage collector. It does so with enough regularity that my plots of memory use versus number of objects declared are always strictly linear (accounting for padding, etc.). – Jim Pivarski Jul 09 '15 at 19:49
-
I was thinking that by allocating new objects and then not referencing them anymore, the garbage collector would automatically run – Bionix1441 Oct 17 '17 at 21:45
-
@PetrHudeček In real world applictions .NET `GC.Collect()` does not collect. In Java `gc()` does. – ajeh Mar 27 '18 at 16:31
-
@ajeh Now that I work with Java, I see you're right about System.gc(). It's just that the documentation for Java says it's a hint, a for .NET, that it's an instruction. – Petr Hudeček Mar 30 '18 at 07:05
-
5@Pacerier if you want deterministic behavior, you can nowadays use the Epsilon garbage collector. It deterministically never collects anything. – Holger Feb 12 '21 at 11:01
-
According to the docs "*When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.*". This sounds deterministic to me. – Daniel F May 30 '21 at 18:27
The jlibs library has a good utility class for garbage collection. You can force garbage collection using a nifty little trick with WeakReference objects.
RuntimeUtil.gc() from the jlibs:
/**
* This method guarantees that garbage collection is
* done unlike <code>{@link System#gc()}</code>
*/
public static void gc() {
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get() != null) {
System.gc();
}
}
-
1This code is broken because a weak ref gets cleared as soon as its referent becomes weakly reachable, which is before it gets cleared from memory. – Marko Topolnik Jun 28 '12 at 20:55
-
@MarkoTopolnik as per the javadoc for WeakReference: "Suppose that the GC determines ... that an object is weakly reachable... it will atomically clear all weak references to that object..." It appears weak refs are cleared by the GC routine, i.e. when the GC has run! – shams Jun 30 '12 at 01:05
-
1You may be conflating the meaning of "GC has run" with "memory has been reclaimed". The object lives on and is not yet even finalized, but you can't access it anymore through the weak reference. A somewhat better way would be to use a `PhantomReference` with a `ReferenceQueue` and then you'd get notified after finalization, but still before cleanup. Finally, even if you successfully detected that the memory for this object was reclaimed, it would still mean very little in a generational GC like HotSpot's. Usually it would coincide with the cleanup of the young generation. – Marko Topolnik Jun 30 '12 at 07:44
-
Expanding on "GC has run"... GC spends a vanishingly small amount of time actually reclaiming memory. Most of the time it works on maintaining its knowledge about how the memory is being used, and has quite a lot other responsibilities -- like taking care of soft, weak and phantom references, filling reference queues, running finalizers, etc. – Marko Topolnik Jun 30 '12 at 09:07
-
1@MarkoTopolnik The OP question was about forcing the GC to run, whether the memory has been reclaimed was not the target in the question. Similarly, whether the GC is generation doesn't matter as it has run on the fragment of memory (the weak reference) we are interested in. Btw, since these are stop-the-world GCs, the GC will have completed all its steps before we get to see the null result fom the get(). – shams Jun 30 '12 at 15:29
-
1The Concurrent Mark and Sweep has been with us for a very long time now, but even concurrency is not the key. You must understand the difference between GC making a run and garbage collection actually happening. A single GC run doesn't necessarily clean anything, it may happen to just do more housekeeping. A final point---if what you are saying were true, why would Java engineers introduce `PhantomReference`? – Marko Topolnik Jun 30 '12 at 16:08
-
@MarkoTopolnik you are adding in the requirement for memory being reclaimed, the OP only required a run of GC. Note that I have no where claimed that the allocated memory has been reclaimed by the GC run :) – shams Jul 02 '12 at 05:06
-
27OP requested, and you claimed to provide, a solution to "force garbage collection". Running the GC subsystem is one thing, actually collecting garbage another. The code sample you provided has clearly the intention to guarantee garbage has been collected. Anyway, this being a very old question it's obviously not about OP's wishes, but utility to the general public. Nobody is interested in "forcing the GC subsystem to run" on its own, with no garbage being collected. In fact, people usually want a guarantee that **all garbage** has been collected. – Marko Topolnik Jul 02 '12 at 07:40
-
@MarkoTopolnik The way I interpret it: if the GC has run, I have forced GC! Memory reclamation requires atleast two GC runs (once when the object is queued for finalization, before the VM runtime calls finalize() and then memory is hopefully deallocated in the next GC run), as is evident from the code it only ensures GC was run once. I repeat: **I haven't claimed that memory has been deallocated by the VM**. – shams Jul 03 '12 at 20:24
-
1The phrase in the Javadoc "garbage collection is done" implies that, and is the obvious intent of the code. The extra complications of the GC subsystem having to make several passes to actually collect garbage is exactly what needs to be abstracted away. Unfortunately, such a thing is impossible in Java. – Marko Topolnik Jul 03 '12 at 20:27
-
@MarkoTopolnik That phrase refers to a run of the GC (which is what System.gc() is intended to do - request the VM for a GC run and make a 'best effort') and not for memory reclamation. I agree we cannot guarantee that in Java, we rely on the VM to deallocate the memory. Once again, forcing garbage collection refers to a run of the GC! – shams Jul 03 '12 at 21:05
-
3So basically, that code does nothing better than `System.gc()`. A `WeakReference` getting cleared has nothing to do with memory reclamation. I personally have tested that code and found it to be useless. The ridiculously simple code `System.gc(); System.gc();` had much better results. – Marko Topolnik Jul 03 '12 at 21:12
-
@MarkoTopolnik That snippet has worked fine for me the few instances I have used it. Reporting your experience to the jlibs team might be useful for them. – shams Jul 03 '12 at 21:16
-
4You probably didn't compare it with the efficiency of `System.gc(); System.gc();`, but it sure would be interesting to know if it ever worked better than that. In fact, just printing how many times it called `System.gc()` would be enough. The chance to ever reach 2 is quite slim. – Marko Topolnik Jul 03 '12 at 21:21
-
-
1If the optimizer does its work well, that code will be completely eliminated. The optimizer can detect that the object will in fact never be used and remove allocation. Hence even the hint `System.gc()` is not reliably sent... (Just think about it - when it reached the loop, there is no guarantee that the WeakReference still points to anything.) – Steffen Heil Mar 15 '16 at 08:03
-
If so, moving the `obj = null` statement as the last statement of the loop should help. Btw, have you seen the code generated by any current JVM optimizer that does such a fine job? – shams Mar 15 '16 at 15:06
-
No, moving `obj = null` anywhere does not help. Every statement is subject to reordering as long as no synchronization is involved. – Steffen Heil Mar 21 '16 at 08:12
-
1@Steffen Heil: right, it would be much better, if it was a `do … while(…)` loop instead. – Holger Nov 24 '16 at 14:36
-
1@shams: yes, recent JVMs are that smart. In that regard, not only is the placement of `obj = null` irrelevant, you don’t even need that statement for the method to become a no-op. – Holger Nov 24 '16 at 14:39
-
3@MarkoTopolnik: 'Nobody is interested in "forcing the GC subsystem to run" on its own, with no garbage being collected'.... Actually I was interested in just this behavior today. I'm thankful this answer was present. My purpose was checking the rotational behavior of the GC log handling, and getting the format of the GC output. This little trick helped me to fill up the GC logs quickly. – erik.weathers Mar 01 '17 at 19:09
-
@erik.weathers Can you give me some details on exactly how it was better than just calling `System.gc(); System.gc();`? – Marko Topolnik Mar 01 '17 at 19:20
-
1@MarkoTopolnik: good point! I replaced the call to that method above with a call to just `System.gc()` (both calls being done within a loop) and both of them worked exactly the same w.r.t. filling up the GC logs. So I retract my support for this method. ;-) – erik.weathers Mar 01 '17 at 23:17
-
1@erik.weathers the reason why you could replace this method with a plain call to `System.gc()` is that there are basically two scenarios a) `System.gc()` does the intended thing already and b) it does not, which makes this answer’s loop hanging forever. With some concurrent garbage collectors, a third option comes into play, the garbage collector may collect the object created in the method, perhaps some more, but ignored an arbitrary amount of actually reclaimable objects. – Holger Feb 12 '21 at 10:57
-
This is admittedly a nifty trick. Unfortunately, after testing it I must testify that it only forces a partial garbage collection. I even tried waiting until 100 weak references have been nulled, and I even placed objects in a queue of 1000 objects so as to guarantee that the objects placed in the weak-reference are old, but still, my tests show that some unreachable objects are almost always still alive after this method has completed. – Mike Nakis Jun 20 '22 at 22:57
The best (if not only) way to force a GC would be to write a custom JVM. I believe the Garbage collectors are pluggable so you could probably just pick one of the available implementations and tweak it.
Note: This is NOT an easy answer.
-
48+1 for lulz. nothing makes frustrating debugging better than someone with a sense of humor. other than an actually useable answer, that is. – jsh Mar 16 '12 at 19:25
Using the Java™ Virtual Machine Tool Interface (JVM TI), the function
jvmtiError ForceGarbageCollection(jvmtiEnv* env)
will "Force the VM to perform a garbage collection." The JVM TI is part of the JavaTM Platform Debugger Architecture (JPDA).

- 203,806
- 29
- 246
- 1,045
YES it is almost possible to forced you have to call to methods in the same order and at the same time this ones are:
System.gc ();
System.runFinalization ();
even if is just one object to clean the use of this two methods at the same time force the garbage collector to use the finalise()
method of unreachable object freeing the memory assigned and doing what the finalize()
method states.
HOWEVER it is a terrible practice to use the garbage collector because the use of it could introduce an over load to the software that may be even worst than on the memory, the garbage collector has his own thread which is not possible to control plus depending on the algorithm used by the gc could take more time and is consider very inefficient, you should check your software if it worst with the help of the gc because it is definitely broke, a good solution must not depend on the gc.
NOTE: just to keep on mind this will works only if in the finalize method is not a reassignment of the object, if this happens the object will keep alive an it will have a resurrection which is technically possible.

- 598
- 6
- 13
-
13*NO*, even these two commands will NOT force a garbage collection. As already mentioned by others, `gc()` is only a hint to run a garbage collection. `runFinalizers()` only runs finalizers on objects "that have been found to be discarded". If the gc did not actually run, there may be no such objects... – Steffen Heil Mar 15 '16 at 07:49
-
1also, [System.runFinalization()](https://docs.oracle.com/javase/10/docs/api/java/lang/System.html#runFinalization()) isn't a guarantee that anything will run; it's possible that nothing will happen at all. It is a _suggestion_ – from Javadoc: "_Calling this method suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run_" – Kaan Dec 25 '19 at 02:31
Under the documentation for OutOfMemoryError it declares that it will not be thrown unless the VM has failed to reclaim memory following a full garbage collection. So if you keep allocating memory until you get the error, you will have already forced a full garbage collection.
Presumably the question you really wanted to ask was "how can I reclaim the memory I think I should be reclaiming by garbage collection?"

- 48,893
- 5
- 92
- 171
You can trigger a GC from the command line. This is useful for batch/crontab:
jdk1.7.0/bin/jcmd <pid> GC.run
See :
-
1Try adding some explanation, comments or description about references – veljasije Aug 20 '13 at 10:58
-
According to the documentation, all this does is call System.gc(), and as it has been stated many times, System.gc() does not force garbage collection. https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html – Cameron McKenzie Dec 23 '20 at 04:09
To manually Request GC (not from System.gc()) :
- Go To : bin folder in JDK eg.-C:\Program Files\Java\jdk1.6.0_31\bin
- Open jconsole.exe
- Connect to the desired local Process.
- Go To memory tab and click perform GC.

- 2,428
- 20
- 16
-
3Oppsss misleading. Please mouse hover the "Perform GC" button. You can request JVM to perform GC but never force. – Kumaran Dec 18 '13 at 05:05
-
@PinkeshSharma, This doesn't **force**. It's a mere request which could probably be ignored entirely. – Pacerier Aug 23 '14 at 06:21
-
@Pacerier In an ideal world yes.. but if you do this you'll see that there is an increase in memory instantly... – Pinkesh Sharma Mar 11 '15 at 07:10
How to Force Java GC
Okay, here are a few different ways to force Java GC.
- Click JConsole's
Perform GC
button - Use JMap's
jmap -histo:live 7544
command where 7544 is the pid - Call the Java Diagnostic Console's
jcmd 7544 GC.run
command - Call
System.gc();
in your code - Call
Runtime.getRuntime().gc()
; in your code
None of these work
Here's the dirty little secret. None of these are guaranteed to work. You really can't force Java GC.
The Java garbage collection algos are non-deterministic, and while all of these methods can motivate the JVM to do GC, you can't actually force it. If the JVM has too much going on and a stop-the-world operation is not possible, these commands will either error out, or they will run but GC won't actually happen.
if (input.equalsIgnoreCase("gc")) {
System.gc();
result = "Just some GC.";
}
if (input.equalsIgnoreCase("runtime")) {
Runtime.getRuntime().gc();
result = "Just some more GC.";
}
Fix the darn problem
If you've got a memory leak or object allocation problem, then fix it. Sitting around with your finger on Java Mission Control's Force Java GC
button only kicks the can down the road. Profile your app with Java Flight Recorder, view the results in VisualVM or JMC, and fix the problem. Trying to force Java GC is a fools game.

- 3,684
- 32
- 28
-
I'm surprised how many people ignore the one valid use case for System.gc(), or actually forcing a GC: Find out how much reachable memory is actually reachable. E.g. you want this during performance testing, and to determine a baseline value for -XmX - obviously you don't want or need it in production. – toolforger May 19 '22 at 14:31
.gc is a candidate for elimination in future releases - a Sun Engineer once commented that maybe fewer than twenty people in the world actually know how to use .gc() - I did some work last night for a few hours on a central / critical data-structure using SecureRandom generated data, at somewhere just past 40,000 objects the vm would slow down as though it had run out of pointers. Clearly it was choking down on 16-bit pointer tables and exhibited classic "failing machinery" behavior.
I tried -Xms and so on, kept bit twiddling until it would run to about 57,xxx something. Then it would run gc going from say 57,127 to 57,128 after a gc() - at about the pace of code-bloat at camp Easy Money.
Your design needs fundamental re-work, probably a sliding window approach.

- 638
- 3
- 6
-
1I have something like that, a lot of objects in memory I can't deallocate them. OutOfMemory exception is thrown, I want to Force GC to test if there is some Infinite Object creation process or these objects are the one used by my system. – Sep 28 '09 at 00:30
-
Sounds like you are working on the same problem I am, pls explain: "Infinite Object creation" ... good research project, maybe you can post a question or something in a java area here ( I'm sort new here and to not know the "Finite Automa" of how the site works ) I tried yesterday and ended up doing file.dat as the compiler complained "too much code" on 40,000 base36 BigIntegers coded as a static final String[] I'm gonna stick my neck here and speculate that the entire JVM is limited on 16-bit pointers, I bet what we have to do is agressively null and read in from disk ... – Nicholas Jordan Sep 30 '09 at 22:50
-
Really, I don't get you. But to be clear about "Infinite Object Creation" I meant that there is some piece of code at my big system do creation of objects whom handles and alive in memory, I could not get this piece of code actually, just gesture!! – Oct 01 '09 at 21:36
-
6Nonsense! There is one obvious case where it should be used: testing code which uses weak references, so that we can make sure that behaviour is correct when weak references get cleared up. – Elias Vasylenko Jul 13 '12 at 15:28
-
While a Sun engineer may have told you this in 2009 or earlier, there is no sign that it is actually going to happen. It is now the end of 2020, and in the last 9 years / 9 Java releases, `gc()` has not been deprecated. Deprecation / removal would break too many existing applications for this to be seriously contemplated, IMO. – Stephen C Dec 28 '20 at 00:29
JVM specification doesn't say anything specific about garbage collection. Due to this, vendors are free to implement GC in their way.
So this vagueness causes uncertainty in garbage collection behavior. You should check your JVM details to know about the garbage collection approaches/algorithms. Also there are options to customize behavior as well.

- 10,309
- 6
- 39
- 55
-
1Good idea, I wonder if there's a particular GC where `System.GC` is guaranteed to "do something" :) – rogerdpack Feb 22 '22 at 20:24
-
You are not and should not be guaranteed a GC sweep on its invocation, as there are layers of references, in fact a tree of references that the GC has to iterate through in order to detach each single node of the tree (reference to the object basically) and yet hold the tree valid. An immediate invocation doesn't sound practical; because, regardless of when it's invoked, GC has to clean the garbage up in a chained hierarchical fashion to not leave any objects in a null referenced state. But, cleaning up our code or rethinking around the logic is the best bet and by far the cleanest one. – Abhay Nagaraj Jul 19 '22 at 19:44
If you need to force garbage collection, perhaps you should consider how you're managing resources. Are you creating large objects that persist in memory? Are you creating large objects (e.g., graphics classes) that have a Disposable
interface and not calling dispose()
when done with it? Are you declaring something at a class level that you only need within a single method?

- 12,864
- 16
- 78
- 107
It would be better if you would describe the reason why you need garbage collection. If you are using SWT, you can dispose resources such as Image
and Font
to free memory. For instance:
Image img = new Image(Display.getDefault(), 16, 16);
img.dispose();
There are also tools to determine undisposed resources.

- 37,593
- 16
- 136
- 187
-
-
1Completely unrelated to the question! No, I'm not using SWT. I'm calling a JNI method that opens a .NET window through a Delphi native layer. I also have a FORTRAN computation core that receives data through a native C++ layer. What does that have to do with anything? Can I force a GC or not? No? :-( – Mostafa Zeinali Jul 03 '18 at 04:09
-
Rebooting the machine is also a way of freeing up memory, although I doubt this answer helps you any more than finding a way of manually invoking garbage collection. – Paul Lammertsma Dec 30 '20 at 13:57
You can try using Runtime.getRuntime().gc()
or use utility method System.gc()
Note: These methods do not ensure GC. And their scope should be limited to JVM rather than programmatically handling it in your application.

- 1,561
- 2
- 20
- 32
-
2As explained in the other answers, those methods do not **force** a (complete) garbage collection run. – Flow Mar 24 '19 at 17:29
Another options is to not create new objects.
Object pooling is away to reduce the need GC in Java.
Object pooling is generally not going to be faster than Object creation (esp for lightweight objects) but it is faster than Garbage Collection. If you created 10,000 objects and each object was 16 bytes. That's 160,000 bytes GC has to reclaim. On the other hand, if you don't need all 10,000 at the same time, you can create a pool to recycle/reuse the objects which eliminates the need to construct new objects and eliminates the need to GC old objects.
Something like this (untested). And if you want it to be thread safe you can swap out the LinkedList for a ConcurrentLinkedQueue.
public abstract class Pool<T> {
private int mApproximateSize;
private LinkedList<T> mPool = new LinkedList<>();
public Pool(int approximateSize) {
mApproximateSize = approximateSize;
}
public T attain() {
T item = mPool.poll();
if (item == null) {
item = newInstance();
}
return item;
}
public void release(T item) {
int approxSize = mPool.size(); // not guaranteed accurate
if (approxSize < mApproximateSize) {
recycle(item);
mPool.add(item);
} else if (approxSize > mApproximateSize) {
decommission(mPool.poll());
}
}
public abstract T newInstance();
public abstract void recycle(T item);
public void decommission(T item) { }
}

- 3,038
- 1
- 17
- 13
We can trigger jmap -histo:live <pid>
using the java runtime. This will force a full GC on heap to mark all the live objects.
public static void triggerFullGC() throws IOException, InterruptedException {
String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
Process process = Runtime.getRuntime().exec(
String.format("jmap -histo:live %s", pid)
);
System.out.println("Process completed with exit code :" + process.waitFor());
}

- 730
- 1
- 5
- 25
I did some experimentation (see https://github.com/mikenakis/ForcingTheJvmToGarbageCollect) trying about a dozen different ways of performing a garbage collection, including ways described in this answer, and more, and I found that there is absolutely no frigging way to deterministically force the JVM to do a complete garbage collection. Even the best answers to this question are only partially successful in that the best they achieve is some garbage collection, but never a guaranteed full garbage collection.
My experimentation has showed that the following code snippet yields the best (least bad) results:
public static void ForceGarbageCollection()
{
long freeMemory = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
for( ; ; )
{
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();
long newFreeMemory = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
if( newFreeMemory == freeMemory )
break;
freeMemory = newFreeMemory;
sleep( 10 );
}
}
Where the sleep()
function is as follows:
private static void sleep( int milliseconds )
{
try
{
Thread.sleep( milliseconds );
}
catch( InterruptedException e )
{
throw new RuntimeException( e );
}
}
Unfortunately, that number 10
in that sleep( 10 )
is magic; it assumes that you are doing a moderate number of memory allocations per second, which incur a moderate amount of finalization. If you are going through objects faster, then 10
might be inadequate and you may need to wait longer. You could set it to 100
to be sure, but no matter what you set it to, there will always be a chance that it will not be enough.
That having been said, in a controlled environment where that 10
is enough, this approach has been observed to consistently eliminate all unreachable objects from memory, while no other approach mentioned in this Q&A does. The experiment code I linked to on github proves so.
In my opinion, the fact that the Java Virtual Machine provides no means of performing a forced-on-demand, unconditional, deterministic, absolutely thorough, stop-the-world garbage collection makes it BROKEN.
To put it in a different way, the creators of the JVM are so full of hubris as to think that they know better than us whether we want to do that or whether we should want to do that. Don't be so arrogant. If something works as if by magic, then some means of bypassing the magic must be provided.

- 56,297
- 11
- 110
- 142
I wanted to force gc, because my code was frozen for a long time when it happened. The aim is to smooth the charge, by regularly cause gc. The solutions listed doesnt forced anything in my environment.
So:
- I request the memory for temporary variable,
- simply, by increments,
- and monitor the memory and stop the operation as soon as gc is triggered.
It works easily but you have to tune.
Runtime rt = Runtime.getRuntime();
double usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
if (usedMB > 1000) // only when necessary
{
byte[][] for_nothing = new byte[10][];
for (int k = 0; k < 10 ; k ++)
for_nothing[k] = new byte[100_000_000];
}
System.gc();
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();

- 3,061
- 1
- 10
- 26
Really, I don't get you. But to be clear about "Infinite Object Creation" I meant that there is some piece of code at my big system do creation of objects whom handles and alive in memory, I could not get this piece of code actually, just gesture!!
This is correct, only gesture. You have pretty much the standard answers already given by several posters. Let's take this one by one:
- I could not get this piece of code actually
Correct, there is no actual jvm - such is only a specification, a bunch of computer science describing a desired behaviour ... I recently dug into initializing Java objects from native code. To get what you want, the only way is to do what is called aggressive nulling. The mistakes if done wrong are so bad doing that we have to limit ourselves to the original scope of the question:
- some piece of code at my big system do creation of objects
Most of the posters here will assume you are saying you are working to an interface, if such we would have to see if you are being handed the entire object or one item at a time.
If you no longer need an object, you can assign null to the object but if you get it wrong there is a null pointer exception generated. I bet you can achieve better work if you use NIO
Any time you or I or anyone else gets: "Please I need that horribly." it is almost universal precursor to near total destruction of what you are trying to work on .... write us a small sample code, sanitizing from it any actual code used and show us your question.
Do not get frustrated. Often what this resolves to is your dba is using a package bought somewhere and the original design is not tweaked for massive data structures.
That is very common.

- 1,187
- 16
- 32

- 638
- 3
- 6
-
Aggressive nulling used to be useful for the JVMs before Hotspot. Afterwards, we have been having a copying collector, where the number of dead objects does not matter. – toolforger May 19 '22 at 14:34
If you are running out of memory and getting an OutOfMemoryException
you can try increasing the amount of heap space available to java by starting you program with java -Xms128m -Xmx512m
instead of just java
. This will give you an initial heap size of 128Mb and a maximum of 512Mb, which is far more than the standard 32Mb/128Mb.

- 1,942
- 3
- 25
- 36
FYI
The method call System.runFinalizersOnExit(true) guarantees that finalizer methods are called before Java shuts down. However, this method is inherently unsafe and has been deprecated. An alternative is to add “shutdown hooks” with the method Runtime.addShutdownHook.
Masarrat Siddiqui

- 27
- 3
-
The flaw with shutdown hooks is that they rarely actually work. Force terminating doesn't work, non-zero exit code doesn't work, and sometimes the (official) JVM simply doesn't run them as long as you need them to run. – ThePyroEagle Dec 22 '15 at 13:31
There is some indirect way for forcing garbage collector. You just need to fill heap with temporary objects until the point when garbage collector will execute. I've made class which forces garbage collector in this way:
class GarbageCollectorManager {
private static boolean collectionWasForced;
private static int refCounter = 0;
public GarbageCollectorManager() {
refCounter++;
}
@Override
protected void finalize() {
try {
collectionWasForced = true;
refCounter--;
super.finalize();
} catch (Throwable ex) {
Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int forceGarbageCollection() {
final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;
int iterationsUntilCollected = 0;
collectionWasForced = false;
if (refCounter < 2)
new GarbageCollectorManager();
while (!collectionWasForced) {
iterationsUntilCollected++;
int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC];
arr = null;
}
return iterationsUntilCollected;
}
}
Usage:
GarbageCollectorManager manager = new GarbageCollectorManager();
int iterationsUntilGcExecuted = manager.forceGarbageCollection();
I don't know how much this method is useful, because it fills heap constantly, but if you have mission critical application which MUST force GC - when this may be the Java portable way to force GC.

- 10,935
- 5
- 50
- 70
-
-
Array size - how many temporary objects (int's) will be generated for GC to start working. – Agnius Vasiliauskas Feb 10 '15 at 08:27
-
-
1Yes, [underscores in numeric literals](http://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html) are valid starting from Java SE 7. This is useful for example as thousands separator in integer as in this case. – Agnius Vasiliauskas Feb 10 '15 at 09:23
-
3You should *never* run such code in a production system. While this code runs in one thread any other thread may also get a OutOfMemoryException, completely reversion the intention of calling this in the first place.... – Steffen Heil Mar 15 '16 at 07:56
-
1@Steffen Heil: …and it may run forever, as garbage collection is not required to always collect all objects (and it’s easy to optimize away the array creation here). Further, garbage collection is not the same as finalization and finalizers are not required to run timely or ever at all. It would be an entirely plausible behavior to defer the finalization of that single pending object until that loop is over. Which leads to the loop never being over… – Holger Jul 04 '17 at 11:12
-
I would be more than happy to hear about better (excluding hints to GC) solution – Agnius Vasiliauskas Jul 05 '17 at 16:41
I would like to add some thing here. Please not that Java runs on Virtual Machine and not actual Machine. The virtual machine has its own way of communication with the machine. It may varry from system to system. Now When we call the GC we ask the Virtual Machine of Java to call the Garbage Collector.
Since the Garbage Collector is with Virtual Machine , we can not force it to do a cleanup there and then. Rather that we queue our request with the Garbage Collector. It depends on the Virtual Machine, after particular time (this may change from system to system, generally when the threshold memory allocated to the JVM is full) the actual machine will free up the space. :D

- 287
- 3
- 3
-
-
This answer is completely confusing the "Java Virtual Machine" (which is a bytecode interpreter) with a "Virtual Machine" (which is a way to emulate a processor on another processor). And no, the JVM isn't delegating GC to a lower-level machine, it has its own GC routines. – toolforger May 19 '22 at 14:36
On OracleJDK 10 with G1 GC, a single call to System.gc()
will cause GC to clean up the Old Collection. I am not sure if GC runs immediately. However, GC will not clean up the Young Collection even if System.gc()
is called many times in a loop. To get GC to clean up the Young Collection, you must allocate in a loop (e.g. new byte[1024]
) without calling System.gc()
. Calling System.gc()
for some reason prevents GC from cleaning up the Young Collection.

- 8,093
- 8
- 50
- 76
If you are using JUnit and Spring, try adding this in every test class:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

- 1,249
- 2
- 17
- 32