How to force garbage collection in Java?
Asked Answered
C

25

273

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?

Culet answered 26/9, 2009 at 13:14 Comment(9)
Perhaps 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.Scudder
A 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.Lavation
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: iwillgetthatjobatgoogle.tumblr.com/post/12591334729/…Peake
Just 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.Outherod
jmap -histo:live <pid> #6418589Clermontferrand
Here'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.Alost
@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.Sunburst
@JustinEthier benchmarkingDensity
Profiling tools like JProfiler seems to be capable of triggering immediate garbage collection.Sailor
S
200

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 an immediate collection though as the garbage collector is non-deterministic.

Scrogan answered 26/9, 2009 at 13:19 Comment(5)
A 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.Colicroot
In 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.).Chalaza
I was thinking that by allocating new objects and then not referencing them anymore, the garbage collector would automatically runTonneau
@PetrHudeček In real world applictions .NET GC.Collect() does not collect. In Java gc() does.Hennessy
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.Comment
Z
63

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();
     }
   }
Zoa answered 2/8, 2011 at 16:19 Comment(25)
This 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.Ephemera
@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!Zoa
You 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.Ephemera
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.Ephemera
@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().Zoa
The 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?Ephemera
@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 :)Zoa
OP 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.Ephemera
@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.Zoa
The 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.Ephemera
@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!Zoa
So 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.Ephemera
@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.Zoa
You 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.Ephemera
This code is just waiting for the next regular gc isn't it?Rowel
If 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.)Ingeborgingelbert
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?Zoa
No, moving obj = null anywhere does not help. Every statement is subject to reordering as long as no synchronization is involved.Ingeborgingelbert
@Steffen Heil: right, it would be much better, if it was a do … while(…) loop instead.Baldheaded
@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.Baldheaded
@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.Southport
@Southport Can you give me some details on exactly how it was better than just calling System.gc(); System.gc();?Ephemera
@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. ;-)Southport
@Southport 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.Baldheaded
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.Thermometer
A
58

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.

Argillaceous answered 27/9, 2009 at 14:7 Comment(0)
L
47

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).

Library answered 24/1, 2013 at 1:45 Comment(0)
S
25

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.

Synecious answered 21/5, 2014 at 5:29 Comment(2)
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...Ingeborgingelbert
also, System.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"Mauritius
H
23

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?"

Hanshansard answered 26/9, 2009 at 14:45 Comment(0)
H
23

You can trigger a GC from the command line. This is useful for batch/crontab:

jdk1.7.0/bin/jcmd <pid> GC.run

See :

Heliogravure answered 20/8, 2013 at 10:38 Comment(2)
Try adding some explanation, comments or description about referencesRansell
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. docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/…Thingumabob
S
17

To manually Request GC (not from System.gc()) :

  1. Go To : bin folder in JDK eg.-C:\Program Files\Java\jdk1.6.0_31\bin
  2. Open jconsole.exe
  3. Connect to the desired local Process.
  4. Go To memory tab and click perform GC.
Scamander answered 14/4, 2013 at 19:3 Comment(3)
Oppsss misleading. Please mouse hover the "Perform GC" button. You can request JVM to perform GC but never force.Serilda
@PinkeshSharma, This doesn't force. It's a mere request which could probably be ignored entirely.Manado
@Manado In an ideal world yes.. but if you do this you'll see that there is an increase in memory instantly...Scamander
T
14

How to Force Java GC

Okay, here are a few different ways to force Java GC.

  1. Click JConsole's Perform GC button
  2. Use JMap's jmap -histo:live 7544 command where 7544 is the pid
  3. Call the Java Diagnostic Console's jcmd 7544 GC.run command
  4. Call System.gc(); in your code
  5. Call Runtime.getRuntime().gc(); in your code

enter image description here

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.

enter image description here

Thingumabob answered 28/12, 2020 at 0:6 Comment(1)
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.Hegyera
R
12

.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.

Reflexion answered 26/9, 2009 at 17:30 Comment(5)
I 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.Culet
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 ...Reflexion
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!!Culet
Nonsense! 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.Sunburst
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.Rika
M
7

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.

Mesmerize answered 10/11, 2012 at 7:23 Comment(2)
Good idea, I wonder if there's a particular GC where System.GC is guaranteed to "do something" :)Marna
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.Boswell
A
4

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?

Anodyne answered 26/9, 2009 at 13:26 Comment(0)
M
1

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.

Mohock answered 26/9, 2009 at 13:25 Comment(3)
what if there is not any dispose method?Alicealicea
Completely 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? :-(Moorman
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.Mohock
B
1

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.

Blanton answered 6/2, 2018 at 4:22 Comment(1)
As explained in the other answers, those methods do not force a (complete) garbage collection run.Mentholated
S
1

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) { }

}
Sev answered 26/9, 2018 at 7:4 Comment(0)
E
1

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());
}
Electrosurgery answered 21/4, 2021 at 8:51 Comment(1)
I tried this, and the result is no better than System.gc()Thermometer
T
0

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.

Thermometer answered 21/6, 2022 at 0:2 Comment(0)
M
0

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(); 
Murrelet answered 5/8, 2022 at 11:12 Comment(0)
R
-1

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:

  1. 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:

  1. 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.

Reflexion answered 2/10, 2009 at 5:17 Comment(1)
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.Hegyera
G
-1

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.

Gorlovka answered 9/3, 2011 at 16:24 Comment(1)
The default memory settings are java -Xms512M -Xmx1024MPenner
S
-2

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

Scientistic answered 7/1, 2013 at 7:11 Comment(1)
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.Penner
N
-2

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.

Na answered 22/10, 2014 at 12:47 Comment(7)
What is "final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;"?Varicocele
Array size - how many temporary objects (int's) will be generated for GC to start working.Na
Is this valid: "_" in a integer?Varicocele
Yes, underscores in numeric literals are valid starting from Java SE 7. This is useful for example as thousands separator in integer as in this case.Na
You 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....Ingeborgingelbert
@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…Baldheaded
I would be more than happy to hear about better (excluding hints to GC) solutionNa
B
-2

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

Baba answered 4/9, 2015 at 3:49 Comment(2)
First sentence of the second paragraph is a non sequitur.Maki
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.Hegyera
P
-2

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.

Pinniped answered 25/1, 2019 at 0:5 Comment(0)
K
-4

If you are using JUnit and Spring, try adding this in every test class:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
Kristeenkristel answered 15/1, 2019 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.