Nicholas
Nicholas

Reputation: 7501

Java Heap Overflow, Forcing Garbage Collection

I've create a trie tree with an array of children. When deleting a word, I set the children null, which I would assume deletes the node(delete is a relative term). I know that null doesn't delete the child, just sets it to null, which when using a large amount of words it causes to overflow the heap.

Running a top on linux, I can see my memory usage spike to 1gb pretty quickly, but if I force garbage collection after the delete (Runtime.gc()) the memory usage goes to 50mb and never above that. From what I'm told, java by default runs garbage collection before a heap overflow happens, but I can't see to make that happen.

Upvotes: 2

Views: 6199

Answers (5)

SyntaxT3rr0r
SyntaxT3rr0r

Reputation: 28293

(this too long for a comment)

Contrarily to popular belief you CAN really force a GC in Java but this is not done using System.gc(). The way to really force a GC is to use JVMTI's ForceGarbageCollection() call. Don't ask me more, I asked a question here and nobody found it interesting (no upvotes) and nobody could answer it, yet JVMTI's ForceGarbageCollection() is how a lot of Java programs like IntelliJ, NetBeans, VisualVM, Eclipse etc. do really force a GC:

Java: How do you really force a GC using JVMTI's ForceGargabeCollection?

Now... You probably do not want to do that and you probably do not want to hint the GC using the "no guarantee" System.gc() call.

At how many words do you start having problems? There are very compact data structure when you need to work with insane number of words. Are you sure you're using the correct data structure and are you sure you're not having leaks?

Upvotes: 5

Enno Shioji
Enno Shioji

Reputation: 26882

OK, you are getting a java.lang.OutOfMemoryError: Java heap space.
Most probably, Runtime.gc() won't help, because if it would, the JVM had already did a gc.

It's probably a memory leak. If I were you, I will review my code carefully and see if some reference is still hold by something.

So the grandchildren aren't deleted? When I do my delete, I simply set it's child node to null, but not the children's children, but those children weren't ever initialized, only create(Node[] children = new Node[26]

If you do children=null , yes, the entire array should be gc'd. Provided that you didn't gave that reference to something.

But who knows what the culprit is. It may not even these "children" Nodes. You might want to use visualVm and find out what object is accumulating. You can use more sophisticated tools like JProfiler and examine the references etc., but if you are simply building a trie, I guess it's simpler to walk-through your code and spot the leak.

Upvotes: 1

crazyscot
crazyscot

Reputation: 11989

An object will only be deleted after it can no longer be reached by links from any accessible object. Is it possible that you still have references to the objects concerned?

By the way, Runtime.gc() is sometimes only a hint that garbage collection should run.

Upvotes: 0

Esko Luontola
Esko Luontola

Reputation: 73615

Are you are referring to the memory not being freed to the OS - i.e. top and similar programs show that the Java process takes 1GB of memory? Even though Java's garbage collector frees the memory from its heap, it can still keep hold of the memory so that future allocations don't need to request for more memory from the OS.

To see how much heap space is actually used by the Java objects, use VisualVM or a similar Java-specific tool. If your machine has lots of memory, then the JVM will use it (IIRC, especially the Server VM is tuned to reserve more memory), but you can always limit it with the -Xmx and other JVM options.

Upvotes: 3

msw
msw

Reputation: 43487

Memory allocated to a process (i.e. the JVM) is not necessarily given back to the OS in Unix. So even though the Java Virtual Machine may have fully garbage collected the heap, the process size may stay the same.

Ordinarily, this may not have much impact as the unused heap will be paged out and not paged back in again. Look at the difference between the Virtual Size (VSZ) and the Resident Set Size (RSS) in the output of ps -u the difference is how many pages are swapped out.

Upvotes: 0

Related Questions