How to force garbage collection in Java?

2018-12-31 03:23发布

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?

21条回答
栀子花@的思念
2楼-- · 2018-12-31 04:22

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();
     }
   }
查看更多
不流泪的眼
3楼-- · 2018-12-31 04:22

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

查看更多
余欢
4楼-- · 2018-12-31 04:23

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 if it is done wrong 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.

查看更多
无色无味的生活
5楼-- · 2018-12-31 04:23

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

查看更多
查无此人
6楼-- · 2018-12-31 04:23

The following code is taken from the assertGC(...) method. It tries to force the nondeterministic garbage collector to collect.

   List<byte[]> alloc = new ArrayList<byte[]>();
   int size = 100000;
   for (int i = 0; i < 50; i++) {
        if (ref.get() == null) {
             // Test succeeded! Week referenced object has been cleared by gc.
             return;
        }
        try {
             System.gc();
        } catch (OutOfMemoryError error) {
             // OK
        }
        try {
             System.runFinalization();
        } catch (OutOfMemoryError error) {
             // OK
        }

        // Approach the jvm maximal allocatable memory threshold
        try {
             // Allocates memory.
             alloc.add(new byte[size]);

             // The amount of allocated memory is increased for the next iteration.
             size = (int)(((double)size) * 1.3);
        } catch (OutOfMemoryError error) {
             // The amount of allocated memory is decreased for the next iteration.
             size = size / 2;
        }

        try {
             if (i % 3 == 0) Thread.sleep(321);
        } catch (InterruptedException t) {
             // ignore
        }
   }

   // Test failed! 

   // Free resources required for testing
   alloc = null;

   // Try to find out who holds the reference.
   String str = null;
   try {
        str = findRefsFromRoot(ref.get(), rootsHint);
   } catch (Exception e) {
        throw new AssertionFailedErrorException(e);
   } catch (OutOfMemoryError err) {
        // OK
   }
   fail(text + ":\n" + str);

Source (I added some comments for clarity): NbTestCase Example

查看更多
栀子花@的思念
7楼-- · 2018-12-31 04:25

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.

查看更多
登录 后发表回答