Is there a way to free memory in Java, similar to C's free() function? Or is setting the object to null and relying on GC the only option?
Java uses managed memory, so the only way you can allocate memory is by using the new operator, and the only way you can deallocate memory is by relying on the garbage collector.
This memory management whitepaper (PDF) may help explain what's going on.
You can also call System.gc() to suggest that the garbage collector run immediately. However, the Java Runtime makes the final decision, not your code.
According to the Java documentation,
Calling the gc method suggests that
the Java Virtual Machine expend effort
toward recycling unused objects in
order to make the memory they
currently occupy available for quick
reuse. When control returns from the
method call, the Java Virtual Machine
has made a best effort to reclaim
space from all discarded objects.
No one seems to have mentioned explicitly setting object references to null, which is a legitimate technique to "freeing" memory you may want to consider.
For example, say you'd declared a List<String> at the beginning of a method which grew in size to be very large, but was only required until half-way through the method. You could at this point set the List reference to null to allow the garbage collector to potentially reclaim this object before the method completes (and the reference falls out of scope anyway).
Note that I rarely use this technique in reality but it's worth considering when dealing with very large data structures.
System.gc();
Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
Not recommended.
Edit: I wrote the original response in 2009. It's now 2015.
Garbage collectors have gotten steadily better in the ~20 years Java's been around. At this point, if you're manually calling the garbage collector, you may want to consider other approaches:
If you're forcing GC on a limited number of machines, it may be worth having a load balancer point away from the current machine, waiting for it to finish serving to connected clients, timeout after some period for hanging connections, and then just hard-restart the JVM. This is a terrible solution, but if you're looking at System.gc(), forced-restarts may be a possible stopgap.
Consider using a different garbage collector. For example, the (new in the last six years) G1 collector is a low-pause model; it uses more CPU overall, but does it's best to never force a hard-stop on execution. Since server CPUs now almost all have multiple cores, this is A Really Good Tradeoff to have available.
Look at your flags tuning memory use. Especially in newer versions of Java, if you don't have that many long-term running objects, consider bumping up the size of newgen in the heap. newgen (young) is where new objects are allocated. For a webserver, everything created for a request is put here, and if this space is too small, Java will spend extra time upgrading the objects to longer-lived memory, where they're more expensive to kill. (If newgen is slightly too small, you're going to pay for it.) For example, in G1:
XX:G1NewSizePercent (defaults to 5; probably doesn't matter.)
XX:G1MaxNewSizePercent (defaults to 60; probably raise this.)
Consider telling the garbage collector you're not okay with a longer pause. This will cause more-frequent GC runs, to allow the system to keep the rest of it's constraints. In G1:
XX:MaxGCPauseMillis (defaults to 200.)
*"I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself."
This is unnecessary. The way the Java GC works is it finds objects that have no reference to them, so if I have an Object x with a reference (=variable) a that points to it, the GC won't delete it, because there is a reference to that object:
a -> x
If you null a than this happens:
a -> null
x
So now x doesn't have a reference pointing to it and will be deleted. The same thing happens when you set a to reference to a different object than x.
So if you have an array arr that references to objects x, y and z and a variable a that references to the array it looks like that:
a -> arr -> x
-> y
-> z
If you null a than this happens:
a -> null
arr -> x
-> y
-> z
So the GC finds arr as having no reference set to it and deletes it, which gives you this structure:
a -> null
x
y
z
Now the GC finds x, y and z and deletes them aswell. Nulling each reference in the array won't make anything better, it will just use up CPU time and space in the code (that said, it won't hurt further than that. The GC will still be able to perform the way it should).
To extend upon the answer and comment by Yiannis Xanthopoulos and Hot Licks (sorry, I cannot comment yet!), you can set VM options like this example:
-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30
In my jdk 7 this will then release unused VM memory if more than 30% of the heap becomes free after GC when the VM is idle. You will probably need to tune these parameters.
While I didn't see it emphasized in the link below, note that some garbage collectors may not obey these parameters and by default java may pick one of these for you, should you happen to have more than one core (hence the UseG1GC argument above).
VM arguments
Update: For java 1.8.0_73 I have seen the JVM occasionally release small amounts with the default settings. Appears to only do it if ~70% of the heap is unused though.. don't know if it would be more aggressive releasing if the OS was low on physical memory.
A valid reason for wanting to free memory from any programm (java or not ) is to make more memory available to other programms on operating system level. If my java application is using 250MB I may want to force it down to 1MB and make the 249MB available to other apps.
I have done experimentation on this.
It's true that System.gc(); only suggests to run the Garbage Collector.
But calling System.gc(); after setting all references to null, will improve performance and memory occupation.
If you really want to allocate and free a block of memory you can do this with direct ByteBuffers. There is even a non-portable way to free the memory.
However, as has been suggested, just because you have to free memory in C, doesn't mean it a good idea to have to do this.
If you feel you really have a good use case for free(), please include it in the question so we can see what you are rtying to do, it is quite likely there is a better way.
Entirely from javacoffeebreak.com/faq/faq0012.html
A low priority thread takes care of garbage collection automatically
for the user. During idle time, the thread may be called upon, and it
can begin to free memory previously allocated to an object in Java.
But don't worry - it won't delete your objects on you!
When there are no references to an object, it becomes fair game for
the garbage collector. Rather than calling some routine (like free in
C++), you simply assign all references to the object to null, or
assign a new class to the reference.
Example :
public static void main(String args[])
{
// Instantiate a large memory using class
MyLargeMemoryUsingClass myClass = new MyLargeMemoryUsingClass(8192);
// Do some work
for ( .............. )
{
// Do some processing on myClass
}
// Clear reference to myClass
myClass = null;
// Continue processing, safe in the knowledge
// that the garbage collector will reclaim myClass
}
If your code is about to request a large amount of memory, you may
want to request the garbage collector begin reclaiming space, rather
than allowing it to do so as a low-priority thread. To do this, add
the following to your code
System.gc();
The garbage collector will attempt to reclaim free space, and your
application can continue executing, with as much memory reclaimed as
possible (memory fragmentation issues may apply on certain platforms).
In my case, since my Java code is meant to be ported to other languages in the near future (Mainly C++), I at least want to pay lip service to freeing memory properly so it helps the porting process later on.
I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself.
But my case is very particular, and I know I'm taking performance hits when doing this.
* "For example, say you'd declared a List at the beginning of a
method which grew in size to be very large, but was only required
until half-way through the method. You could at this point set the
List reference to null to allow the garbage collector to potentially
reclaim this object before the method completes (and the reference
falls out of scope anyway)." *
This is correct, but this solution may not be generalizable. While setting a List object reference to null -will- make memory available for garbage collection, this is only true for a List object of primitive types. If the List object instead contains reference types, setting the List object = null will not dereference -any- of the reference types contained -in- the list. In this case, setting the List object = null will orphan the contained reference types whose objects will not be available for garbage collection unless the garbage collection algorithm is smart enough to determine that the objects have been orphaned.
Althrough java provides automatic garbage collection sometimes you will want to know how large the object is and how much of it is left .Free memory using programatically import java.lang; and Runtime r=Runtime.getRuntime(); to obtain values of memory using mem1=r.freeMemory(); to free memory call the r.gc(); method and the call freeMemory()
Recommendation from JAVA is to assign to null
From https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
Explicitly assigning a null value to variables that are no longer needed helps the garbage collector to identify the parts of memory that can be safely reclaimed. Although Java provides memory management, it does not prevent memory leaks or using excessive amounts of memory.
An application may induce memory leaks by not releasing object references. Doing so prevents the Java garbage collector from reclaiming those objects, and results in increasing amounts of memory being used. Explicitly nullifying references to variables after their use allows the garbage collector to reclaim memory.
One way to detect memory leaks is to employ profiling tools and take memory snapshots after each transaction. A leak-free application in steady state will show a steady active heap memory after garbage collections.
Related
Is there a way to free memory in Java, similar to C's free() function? Or is setting the object to null and relying on GC the only option?
Java uses managed memory, so the only way you can allocate memory is by using the new operator, and the only way you can deallocate memory is by relying on the garbage collector.
This memory management whitepaper (PDF) may help explain what's going on.
You can also call System.gc() to suggest that the garbage collector run immediately. However, the Java Runtime makes the final decision, not your code.
According to the Java documentation,
Calling the gc method suggests that
the Java Virtual Machine expend effort
toward recycling unused objects in
order to make the memory they
currently occupy available for quick
reuse. When control returns from the
method call, the Java Virtual Machine
has made a best effort to reclaim
space from all discarded objects.
No one seems to have mentioned explicitly setting object references to null, which is a legitimate technique to "freeing" memory you may want to consider.
For example, say you'd declared a List<String> at the beginning of a method which grew in size to be very large, but was only required until half-way through the method. You could at this point set the List reference to null to allow the garbage collector to potentially reclaim this object before the method completes (and the reference falls out of scope anyway).
Note that I rarely use this technique in reality but it's worth considering when dealing with very large data structures.
System.gc();
Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
Not recommended.
Edit: I wrote the original response in 2009. It's now 2015.
Garbage collectors have gotten steadily better in the ~20 years Java's been around. At this point, if you're manually calling the garbage collector, you may want to consider other approaches:
If you're forcing GC on a limited number of machines, it may be worth having a load balancer point away from the current machine, waiting for it to finish serving to connected clients, timeout after some period for hanging connections, and then just hard-restart the JVM. This is a terrible solution, but if you're looking at System.gc(), forced-restarts may be a possible stopgap.
Consider using a different garbage collector. For example, the (new in the last six years) G1 collector is a low-pause model; it uses more CPU overall, but does it's best to never force a hard-stop on execution. Since server CPUs now almost all have multiple cores, this is A Really Good Tradeoff to have available.
Look at your flags tuning memory use. Especially in newer versions of Java, if you don't have that many long-term running objects, consider bumping up the size of newgen in the heap. newgen (young) is where new objects are allocated. For a webserver, everything created for a request is put here, and if this space is too small, Java will spend extra time upgrading the objects to longer-lived memory, where they're more expensive to kill. (If newgen is slightly too small, you're going to pay for it.) For example, in G1:
XX:G1NewSizePercent (defaults to 5; probably doesn't matter.)
XX:G1MaxNewSizePercent (defaults to 60; probably raise this.)
Consider telling the garbage collector you're not okay with a longer pause. This will cause more-frequent GC runs, to allow the system to keep the rest of it's constraints. In G1:
XX:MaxGCPauseMillis (defaults to 200.)
*"I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself."
This is unnecessary. The way the Java GC works is it finds objects that have no reference to them, so if I have an Object x with a reference (=variable) a that points to it, the GC won't delete it, because there is a reference to that object:
a -> x
If you null a than this happens:
a -> null
x
So now x doesn't have a reference pointing to it and will be deleted. The same thing happens when you set a to reference to a different object than x.
So if you have an array arr that references to objects x, y and z and a variable a that references to the array it looks like that:
a -> arr -> x
-> y
-> z
If you null a than this happens:
a -> null
arr -> x
-> y
-> z
So the GC finds arr as having no reference set to it and deletes it, which gives you this structure:
a -> null
x
y
z
Now the GC finds x, y and z and deletes them aswell. Nulling each reference in the array won't make anything better, it will just use up CPU time and space in the code (that said, it won't hurt further than that. The GC will still be able to perform the way it should).
To extend upon the answer and comment by Yiannis Xanthopoulos and Hot Licks (sorry, I cannot comment yet!), you can set VM options like this example:
-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30
In my jdk 7 this will then release unused VM memory if more than 30% of the heap becomes free after GC when the VM is idle. You will probably need to tune these parameters.
While I didn't see it emphasized in the link below, note that some garbage collectors may not obey these parameters and by default java may pick one of these for you, should you happen to have more than one core (hence the UseG1GC argument above).
VM arguments
Update: For java 1.8.0_73 I have seen the JVM occasionally release small amounts with the default settings. Appears to only do it if ~70% of the heap is unused though.. don't know if it would be more aggressive releasing if the OS was low on physical memory.
A valid reason for wanting to free memory from any programm (java or not ) is to make more memory available to other programms on operating system level. If my java application is using 250MB I may want to force it down to 1MB and make the 249MB available to other apps.
I have done experimentation on this.
It's true that System.gc(); only suggests to run the Garbage Collector.
But calling System.gc(); after setting all references to null, will improve performance and memory occupation.
If you really want to allocate and free a block of memory you can do this with direct ByteBuffers. There is even a non-portable way to free the memory.
However, as has been suggested, just because you have to free memory in C, doesn't mean it a good idea to have to do this.
If you feel you really have a good use case for free(), please include it in the question so we can see what you are rtying to do, it is quite likely there is a better way.
Entirely from javacoffeebreak.com/faq/faq0012.html
A low priority thread takes care of garbage collection automatically
for the user. During idle time, the thread may be called upon, and it
can begin to free memory previously allocated to an object in Java.
But don't worry - it won't delete your objects on you!
When there are no references to an object, it becomes fair game for
the garbage collector. Rather than calling some routine (like free in
C++), you simply assign all references to the object to null, or
assign a new class to the reference.
Example :
public static void main(String args[])
{
// Instantiate a large memory using class
MyLargeMemoryUsingClass myClass = new MyLargeMemoryUsingClass(8192);
// Do some work
for ( .............. )
{
// Do some processing on myClass
}
// Clear reference to myClass
myClass = null;
// Continue processing, safe in the knowledge
// that the garbage collector will reclaim myClass
}
If your code is about to request a large amount of memory, you may
want to request the garbage collector begin reclaiming space, rather
than allowing it to do so as a low-priority thread. To do this, add
the following to your code
System.gc();
The garbage collector will attempt to reclaim free space, and your
application can continue executing, with as much memory reclaimed as
possible (memory fragmentation issues may apply on certain platforms).
In my case, since my Java code is meant to be ported to other languages in the near future (Mainly C++), I at least want to pay lip service to freeing memory properly so it helps the porting process later on.
I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself.
But my case is very particular, and I know I'm taking performance hits when doing this.
* "For example, say you'd declared a List at the beginning of a
method which grew in size to be very large, but was only required
until half-way through the method. You could at this point set the
List reference to null to allow the garbage collector to potentially
reclaim this object before the method completes (and the reference
falls out of scope anyway)." *
This is correct, but this solution may not be generalizable. While setting a List object reference to null -will- make memory available for garbage collection, this is only true for a List object of primitive types. If the List object instead contains reference types, setting the List object = null will not dereference -any- of the reference types contained -in- the list. In this case, setting the List object = null will orphan the contained reference types whose objects will not be available for garbage collection unless the garbage collection algorithm is smart enough to determine that the objects have been orphaned.
Althrough java provides automatic garbage collection sometimes you will want to know how large the object is and how much of it is left .Free memory using programatically import java.lang; and Runtime r=Runtime.getRuntime(); to obtain values of memory using mem1=r.freeMemory(); to free memory call the r.gc(); method and the call freeMemory()
Recommendation from JAVA is to assign to null
From https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
Explicitly assigning a null value to variables that are no longer needed helps the garbage collector to identify the parts of memory that can be safely reclaimed. Although Java provides memory management, it does not prevent memory leaks or using excessive amounts of memory.
An application may induce memory leaks by not releasing object references. Doing so prevents the Java garbage collector from reclaiming those objects, and results in increasing amounts of memory being used. Explicitly nullifying references to variables after their use allows the garbage collector to reclaim memory.
One way to detect memory leaks is to employ profiling tools and take memory snapshots after each transaction. A leak-free application in steady state will show a steady active heap memory after garbage collections.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Forcing Garbage Collection in Java?
Can I Force Garbage Collection in Java by any means?
System.gc() is just a suggestion.It's useless.
When I know for sure that some resources won't be used any more,why can't I force to clean them?
Just like delete() in C++ and free() in C?
When there are lots of resources that can't be reused,this can really suck the performance.All that we can do is sleep().
Any solutions?Thanks
Nope, System.gc() is as close as you can get. Java isn't C or C++, the JVM manages memory for you, so you don't have that kind of fine grained control. If you set objects you're no longer using to null, or loose all references, they will get cleaned up. And the GC is pretty smart, so it should take good care of you.
That said, if you are on a unix box, and force a thread dump (kill -3), it'll pretty much force garbage collection.
You shouldn't be trying to force GC - if you are running low on memory then you have a memory leak somewhere. Forcing GC at that point won't help, because if you are holding a reference to the object then it still won't be garbage collected.
What you need to do is solve the real problem, and make sure you are not holding references to objects you are not using any more.
Some common culprits:
Holding lots of references in a large object graph that never get cleared up. Either set references to null when you don't need them any more, or better still simplify your object graph so it doesn't need all the extra long-term references.
Caching objects in a hashmap or something similar that grows huge over time. Stop doing this, or use something like Google's CacheBuilder to create a proper soft reference cache.
Using String.intern() excessively on large numbers of different strings over time.
References with larger scope than they need. Are you using an instance variable when it could be a local variable, for example?
There is no way to explicitly instruct the JVM to collect garbage. This is only performed when the system needs the resources.
The only two actions I'm aware of to potentially get the GC running are the following:
As you stated, attempt to "suggest" that GC now would be a good time by called System.gc().
Set any references you are not using to the null reference to make the elements eligible for collection.
On my second point, see the answer here: Garbage collector in java - set an object null. In essence, if you don't make the objects you don't need available for garbage collection (by losing the reference you have to it) then there is no reason for the garbage collector to run, because it's unaware of any available garbage.
In addition, it's important to consider why/how those objects in memory are affecting performance:
Are you getting lots of OutOfMemoryExceptions? This could be resolved by point #2 and by increasing the available heap space for the JVM.
Have you done measurements to see that more objects in the JVM's allocated heap space makes a difference in performance? Determining when you could let references to objects go earlier could help reduce these issues.
I have created an object in Java, Named FOO. FOO contains a large amount of data.. I don't know say for a ten mega byte text file that I have pulled into ram for manipulation.(This is just an example)
This is clearly a huge amount of space and I want to deallocate it from memory. I set FOO to NULL.
Will this free up that space in memory automatically?
or
Will the memory taken by the loaded text file be around until automatic garbage collection?
When you set the reference of any object to null, it becomes available for garbage collection. It still occupies the memory until the garbage collector actually runs. There are no guarantees regarding when GC will run except that it will definitely run and reclaim memory from unreachable objects before an OutOfMemoryException is thrown.
You can call System.gc() to request garbage collection, however, that's what it is - a request. It is upto GC's discretion to run.
Using a WeakReference can help in some cases. See this article by Brian Goetz.
Actually the object is not named FOO. FOO is the name of a variable which is not the object; the variable contains a reference to the object. There could be several distinct variables containing references to the same object.
The garbage collector works by automatically detecting unreachable objects: these are objects which the application cannot use anymore because it has irretrievably forgotten where they are (the application may possibly access any object for which it has a reference to, including the references stored in field in objects it can access, and so on).
When you set FOO = null, assuming that FOO contained at that point the last reachable reference to the object, then the memory is released immediately, in the following sense: at the very clock cycle at which null is set in FOO, the object becomes unreachable. Therefore, the garbage collector will notice that unreachable object and reclaim the corresponding memory block; that is, the GC will do that the next time it can be bothered to run. Of course, the actual bits which constitute the object may linger a bit in memory; but that block is nonetheless "free" since the memory allocator will automatically run the GC when free memory is tight. From the application point of view, the object is as good as dead and the corresponding memory is free since that memory will be reused the next time the application needs it. The whole thing is automatic.
Things are a bit more complex with regards to the operating system. If an unreachable object is free memory from the application point of view, it is still, as far as the OS is concerned, a block of RAM dedicated to the running process. That block of RAM may be given back to the OS only when the GC (which is, at the OS level, a part of the process) actually runs, notices that the object is unreachable, and condescends to give the block back to the OS. When the GC runs heavily depends on the GC technology and how the application allocates objects; also, some GC will never give back the block the OS at all (the GC knows that the block it free, the memory allocator will reuse it at will, but not other processes).
System.gc() is a hint to the VM, so that it runs the GC now. Formally, it is only a hint, and the VM is free to ignore it. In practice, it runs the GC, unless the VM was instructed not to obey such commands (with Sun's JVM, this is a matter of a specific command-line flag). Even if the GC runs, it does not necessarily give back the memory to the operating system. System.gc() is not terribly useful.
Setting foo = null; does not mean that foo will be garbage collected immediately. Instead, it will be collected when the GC next runs, if it can be. When foo is collected, any objects for which it holds the sole reference will also be eligible for collection and therefore collected.
Note that even calling System.gc() does not guarantee that that JVM will do it right away.
System.gc() is just a request and there is no guarantee that it's effect immediately.
There's no guarantee that JVM will do it right away, you can try to force it by using System.gc()
The garbage collector will free the memory after you "destroy" the reference. i.3 Setting the object reference to null. You can use forced garbage collection option but you should use it with care. The Garbage collector is designed to use an optimized schedule so calling the System.gc() may ruin the rhythem and possibly have less performance due to unnecessary task switching.
Alternatively you can think about a way that allows you to not to load large amounts of data into memory. If you can gain that by improving your code that would be much better.
Is there any possibility that a object which is not referenced anywhere and still existing on heap. I mean is there a possibility that a unused object getting escaped from garbage collector and be there on the heap until the end of the application.
Wanted to know because if it is there, then while coding i can be more cautious.
If an object is no longer referenced, it does still exist on the heap, but it is also free to be garbage-collected (unless we are talking Class objects, which live in PermGen space and never get garbage-collected - but this is generally not something you need to worry about).
There is no guarantee on how soon that will be, but your application will not run out of memory before memory from those objects is reclaimed.
However, garbage collection does involve overhead, so if you are creating more objects than you need to and can easily create less, then by all means do so.
Edit: in response to your comment, if an object is truly not referenced by anything, it will be reclaimed during garbage collection (assuming you are using the latest JVM from Sun; I can't speak toward other implementations). The reason why is as follows: all objects are allocated contiguously on the heap. When GC is to happen, the JVM follows all references to "mark" objects that it knows are reachable - these objects are then moved into another, clean area. The old area is then considered to be free memory. Anything that cannot be found via a reference cannot be moved. The point is that the GC does not need to "find" the unreferenced objects. If anything, I would be more worried about objects that are still referenced when they are not intended to be, which will cause memory leaks.
You should know that, before a JVM throws an out-of-memory exception, it will have garbage collected everything possible.
If an instance is no longer referenced, it is a possible candidate for garbage collection. This means, that sooner or later it can be removed but there are no guaranties. If you do not run out of of memory, the garbage collector might not even run, thus the instance my be there until the program ends.
The CG system is very good at finding not referenced objects. There is a tiny, tiny chance that you end up keeping a weird mix of references where the garbage collector can not decide for sure if the object is no longer referenced or not. But this would be a bug in the CG system and nothing you should worry about while coding.
It depends on when and how often the object is used. If you allocate something then deallocate (i.e., remove all references to it) it immediately after, it will stay in "new" part of the heap and will probably be knocked out on the next garbage collection run.
If you allocate an object at the beginning of your program and keep it around for a while (if it survives through several garbage collections), it will get promoted to "old" status. Objects in that part of the heap are less likely to be collected later.
If you want to know all the nitty-gitty details, check out some of Sun's gc documentation.
Yes; imagine something like this:
Foo foo = new Foo();
// do some work here
while(1) {};
foo.someOp(); // if this is the only reference to foo,
// it's theoreticaly impossible to reach here, so it
// should be GC-ed, but all GC systems I know of will
// not Gc it
I am using definition of: garbage = object that can never be reached in any execution of the code.
Garbage collection intentionally makes few guarantees about WHEN the objects are collected. If memory never gets too tight, it's entirely possible that an unreferenced object won't be collected by the time the program ends.
The garbage collector will eventually reclaim all unreachable objects. Note the "eventually": this may take some time. You can somewhat force the issue with System.gc() but this is rarely a good idea (if used without discretion, then performance may decrease).
What can happen is that an object is "unused" (as in: the application will not use it anymore) while still being "reachable" (the GC can find a path of references from one of its roots -- static fields, local variables -- to the object). If you are not too messy with your objects and structures then you will not encounter such situations. A rule of thumb would be: if the application seems to take too much RAM, run a profiler on it; if thousands of instances of the same class have accumulated without any apparent reason, then there may be some fishy code somewhere. Correction often involves explicitly setting a field to null to avoid referencing an object for too long.
This is theoretically possible (there is no guarantee the GC will always find all objects), but should not worry you for any real application - it usually does not happen and certainly does not affect a significant chunk of memory.
In theory, the garbage collector will find all unused objects. There could, of course, be bugs in the garbage collector…
That said, "In theory there is no difference between theory and practice, in practice, there is." Under some, mostly older, garbage collectors, if an object definition manages to reach the permanent generation, then it will no longer be garbage collected under any circumstances. This only applied to Class definitions that were loaded, not to regular objects that were granted tenured status.
Correspondingly, if you have a static reference to an object, that takes up space in the "regular" object heap, this could conceivably cause problems, since you only need to hold a reference to the class definition from your class definition, and that static data cannot be garbage collected, even if you don't actually refer to any instances of the class itself.
In practice though, this is a very unlikely event, and you shouldn't need to worry about it. If you are super concerned about performance, then creating lots of "long-lived" objects, that is, those that escape "escape-analysis", will create extra work for the garbage collector. For 99.99% of coders this is a total non-issue though.
My advice - Don't worry about it.
Reason - It is possible for a non-referenced object to stay on the heap for some time, but it is very unlikely to adversely affect you because it is guaranteed to be reclaimed before you get an out of memory error.
In general, all objects to which there are no live hard references, will be garbage-collected. This is what you should assume and code for. However, the exact moment this happens is not predictable.
Just for completeness, two tricky situations [which you are unlikely to run into] come into my mind:
Bugs in JVM or garbage collector code
So called invisible references - they rarely matter but I did have to take them into account one or two times during the last 5 years in a performance-sensitive application I work on
Is there a way to free memory in Java, similar to C's free() function? Or is setting the object to null and relying on GC the only option?
Java uses managed memory, so the only way you can allocate memory is by using the new operator, and the only way you can deallocate memory is by relying on the garbage collector.
This memory management whitepaper (PDF) may help explain what's going on.
You can also call System.gc() to suggest that the garbage collector run immediately. However, the Java Runtime makes the final decision, not your code.
According to the Java documentation,
Calling the gc method suggests that
the Java Virtual Machine expend effort
toward recycling unused objects in
order to make the memory they
currently occupy available for quick
reuse. When control returns from the
method call, the Java Virtual Machine
has made a best effort to reclaim
space from all discarded objects.
No one seems to have mentioned explicitly setting object references to null, which is a legitimate technique to "freeing" memory you may want to consider.
For example, say you'd declared a List<String> at the beginning of a method which grew in size to be very large, but was only required until half-way through the method. You could at this point set the List reference to null to allow the garbage collector to potentially reclaim this object before the method completes (and the reference falls out of scope anyway).
Note that I rarely use this technique in reality but it's worth considering when dealing with very large data structures.
System.gc();
Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
Not recommended.
Edit: I wrote the original response in 2009. It's now 2015.
Garbage collectors have gotten steadily better in the ~20 years Java's been around. At this point, if you're manually calling the garbage collector, you may want to consider other approaches:
If you're forcing GC on a limited number of machines, it may be worth having a load balancer point away from the current machine, waiting for it to finish serving to connected clients, timeout after some period for hanging connections, and then just hard-restart the JVM. This is a terrible solution, but if you're looking at System.gc(), forced-restarts may be a possible stopgap.
Consider using a different garbage collector. For example, the (new in the last six years) G1 collector is a low-pause model; it uses more CPU overall, but does it's best to never force a hard-stop on execution. Since server CPUs now almost all have multiple cores, this is A Really Good Tradeoff to have available.
Look at your flags tuning memory use. Especially in newer versions of Java, if you don't have that many long-term running objects, consider bumping up the size of newgen in the heap. newgen (young) is where new objects are allocated. For a webserver, everything created for a request is put here, and if this space is too small, Java will spend extra time upgrading the objects to longer-lived memory, where they're more expensive to kill. (If newgen is slightly too small, you're going to pay for it.) For example, in G1:
XX:G1NewSizePercent (defaults to 5; probably doesn't matter.)
XX:G1MaxNewSizePercent (defaults to 60; probably raise this.)
Consider telling the garbage collector you're not okay with a longer pause. This will cause more-frequent GC runs, to allow the system to keep the rest of it's constraints. In G1:
XX:MaxGCPauseMillis (defaults to 200.)
*"I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself."
This is unnecessary. The way the Java GC works is it finds objects that have no reference to them, so if I have an Object x with a reference (=variable) a that points to it, the GC won't delete it, because there is a reference to that object:
a -> x
If you null a than this happens:
a -> null
x
So now x doesn't have a reference pointing to it and will be deleted. The same thing happens when you set a to reference to a different object than x.
So if you have an array arr that references to objects x, y and z and a variable a that references to the array it looks like that:
a -> arr -> x
-> y
-> z
If you null a than this happens:
a -> null
arr -> x
-> y
-> z
So the GC finds arr as having no reference set to it and deletes it, which gives you this structure:
a -> null
x
y
z
Now the GC finds x, y and z and deletes them aswell. Nulling each reference in the array won't make anything better, it will just use up CPU time and space in the code (that said, it won't hurt further than that. The GC will still be able to perform the way it should).
To extend upon the answer and comment by Yiannis Xanthopoulos and Hot Licks (sorry, I cannot comment yet!), you can set VM options like this example:
-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30
In my jdk 7 this will then release unused VM memory if more than 30% of the heap becomes free after GC when the VM is idle. You will probably need to tune these parameters.
While I didn't see it emphasized in the link below, note that some garbage collectors may not obey these parameters and by default java may pick one of these for you, should you happen to have more than one core (hence the UseG1GC argument above).
VM arguments
Update: For java 1.8.0_73 I have seen the JVM occasionally release small amounts with the default settings. Appears to only do it if ~70% of the heap is unused though.. don't know if it would be more aggressive releasing if the OS was low on physical memory.
A valid reason for wanting to free memory from any programm (java or not ) is to make more memory available to other programms on operating system level. If my java application is using 250MB I may want to force it down to 1MB and make the 249MB available to other apps.
I have done experimentation on this.
It's true that System.gc(); only suggests to run the Garbage Collector.
But calling System.gc(); after setting all references to null, will improve performance and memory occupation.
If you really want to allocate and free a block of memory you can do this with direct ByteBuffers. There is even a non-portable way to free the memory.
However, as has been suggested, just because you have to free memory in C, doesn't mean it a good idea to have to do this.
If you feel you really have a good use case for free(), please include it in the question so we can see what you are rtying to do, it is quite likely there is a better way.
Entirely from javacoffeebreak.com/faq/faq0012.html
A low priority thread takes care of garbage collection automatically
for the user. During idle time, the thread may be called upon, and it
can begin to free memory previously allocated to an object in Java.
But don't worry - it won't delete your objects on you!
When there are no references to an object, it becomes fair game for
the garbage collector. Rather than calling some routine (like free in
C++), you simply assign all references to the object to null, or
assign a new class to the reference.
Example :
public static void main(String args[])
{
// Instantiate a large memory using class
MyLargeMemoryUsingClass myClass = new MyLargeMemoryUsingClass(8192);
// Do some work
for ( .............. )
{
// Do some processing on myClass
}
// Clear reference to myClass
myClass = null;
// Continue processing, safe in the knowledge
// that the garbage collector will reclaim myClass
}
If your code is about to request a large amount of memory, you may
want to request the garbage collector begin reclaiming space, rather
than allowing it to do so as a low-priority thread. To do this, add
the following to your code
System.gc();
The garbage collector will attempt to reclaim free space, and your
application can continue executing, with as much memory reclaimed as
possible (memory fragmentation issues may apply on certain platforms).
In my case, since my Java code is meant to be ported to other languages in the near future (Mainly C++), I at least want to pay lip service to freeing memory properly so it helps the porting process later on.
I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself.
But my case is very particular, and I know I'm taking performance hits when doing this.
* "For example, say you'd declared a List at the beginning of a
method which grew in size to be very large, but was only required
until half-way through the method. You could at this point set the
List reference to null to allow the garbage collector to potentially
reclaim this object before the method completes (and the reference
falls out of scope anyway)." *
This is correct, but this solution may not be generalizable. While setting a List object reference to null -will- make memory available for garbage collection, this is only true for a List object of primitive types. If the List object instead contains reference types, setting the List object = null will not dereference -any- of the reference types contained -in- the list. In this case, setting the List object = null will orphan the contained reference types whose objects will not be available for garbage collection unless the garbage collection algorithm is smart enough to determine that the objects have been orphaned.
Althrough java provides automatic garbage collection sometimes you will want to know how large the object is and how much of it is left .Free memory using programatically import java.lang; and Runtime r=Runtime.getRuntime(); to obtain values of memory using mem1=r.freeMemory(); to free memory call the r.gc(); method and the call freeMemory()
Recommendation from JAVA is to assign to null
From https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
Explicitly assigning a null value to variables that are no longer needed helps the garbage collector to identify the parts of memory that can be safely reclaimed. Although Java provides memory management, it does not prevent memory leaks or using excessive amounts of memory.
An application may induce memory leaks by not releasing object references. Doing so prevents the Java garbage collector from reclaiming those objects, and results in increasing amounts of memory being used. Explicitly nullifying references to variables after their use allows the garbage collector to reclaim memory.
One way to detect memory leaks is to employ profiling tools and take memory snapshots after each transaction. A leak-free application in steady state will show a steady active heap memory after garbage collections.