Java Assignment Memory Leaks - java

I have to assume that the following method doesn't leak memory:
public final void setData(final Integer p_iData)
{
data = p_iData;
}
Where data is a property of some class.
Every time the method gets called, a new Integer is replacing the currently existing data reference. So what's happening with the current/old data?
Java has to be doing something under the hood; otherwise we'd have to null-out any objects every time an object is assigned.

Simplistic explanation:
Periodically the garbage collector looks at all the objects in the system, and sees which aren't reachable any more from live references. It frees any objects which are no longer reachable.
Note that your method does not create a new Integer object at all. A reference to the same Integer object could be passed in time and time again, for example.
The reality of garbage collection is a lot more complicated than this:
Modern GCs tend to be generational, assuming that most objects are short-lived, so it doesn't need to check the whole (possibly large) heap as often; it can just check "recent" objects for liveness frequently
Objects can have finalizers - code to be run before they're garbage collected. This delays garbage collection of such objects by a cycle, and the object could even "resurrect" itself by making itself reachable
Modern GCs can collect in parallel, and have numerous tweaking options

Java is a garbage-collected language.
Once there are no more live references to an object, it becomes eligible for garbage collection. The collector runs from time to time and will reclaim the object's memory.
In a nutshell, your code is 100% correct and is not leaking memory.

It gets garbage collected eventually.

if there is no ther reference to data, the garbage collector of java will clean the old data up and free the memory

Actually, since Integer is an object not a primitive type, the line:
data = p_iData;
is updating a reference.
Now, the old object that this.data used to point to will be examined by the GC to determine if there are no more references to that object. If not, that object is destroyed and the memory is freed (at some later time)

If the object previously referenced by data is no longer referenced by any object structure that is referenced from any running thread it is eligible for garbage collecion. GC is performed by Java in the background to free the memory of unused objects.

i want to show one example to you
in some code :
int x;
x=10;
x=20;
initially i assigned x to 10
again x to 20
first reference memory will be handled by Java GC.
Java GC is a thread tht run continuously and checked unreferenced memory and clean it .

Related

Memory leak using autoboxing

I was following tutorial and below was the example for auto boxing memory leak.
package com.example.memoryleak;
public class Adder {
public long addIncremental(long l) {
Long sum=0L;
sum =sum+l;
return sum;
}
public static void main(String[] args) {
Adder adder = new Adder();
for(long ;i<1000;i++) {
adder.addIncremental(i);
}
}
}
Now, I could understand that unnecessary objects would be created because of autoboxing but how it caused memory leak, the way I understand is that memory leak is caused when you are holding a strong reference to a dead object. Now, in this case once I have came out of the FOR loop there would be no strong references to those Long objects then how it caused memory leak?
Please note I want to understand how it caused memory leak, I know those objects were unnecessary.
The other answers are correct: this is not a memory leak.
The code you are showing creates object on a very high rate; and they are subject to garbage collection immediately. None of of these "temp" objects is somehow forgotten; they all get eligible for collection; and the GC will collect them at some point.
A memory leak refers to situations where the used memory keeps ever increasing - without the objects ever becoming eligible for garbage collection.
Given the comment that asks about the "cache" example that uses a map:
as long as there is a single (strong!) reference to the map object from another object that is "alive" in GC terms, that map is "alive". And therefore: all objects stored within that map are alive (not eligible for GC)
when the last reference to that map vanishes, the map itself becomes eligible for the GC. Same is true for the values within the map - unless there is some other reference to such a value which is still alive.
Cite from link you provided:
Can you spot the memory leak?
Here I made a mistake. Instead of taking the primitive long for the sum, I took the Long (wrapper class), which is the cause of the memory leak. Due to auto-boxing, sum=sum+l; creates a new object in every iteration, so 1000 unnecessary objects will be created. Please avoid mixing and matching between primitive and wrapper classes. Try to use primitive as much as you can.
Actually, there is no memory leak here. Better say, it produces some redundant memory usage and garbage collection.
If you want to simulate real memory leak refer to this question: Creating a memory leak with Java.
Also, as a result of adder.addIncremental(i); is ignored there could be some JVM optimizations for this code.
If you take a look at plots of memory you will see that memory usage is quite stable from GC cycle to cycle.
For example:
Can you spot the memory leak?
Here I made a mistake. Instead of taking the primitive long for the
sum, I took the Long (wrapper class), which is the cause of the memory
leak. Due to auto-boxing, sum=sum+l; creates a new object in every
iteration, so 1000 unnecessary objects will be created.
This quoter from tutorial is wrong. In this example you will have no memory leaks but just not efficient memory using.

Where does return value go in java if no variable assigned to accept it?

Let's say a method returns some value, but when I call it, I don't assign any variable to accept this RV. Then where does it go? Will GC collect it? Would it be a problem if I use this kind of method tons of times in my code?
Then where does it go?
It doesn't go anywhere. The value / reference is simply discarded. It is as if you assigned it to a local variable that immediately goes out of scope.
Will GC collect it?
It will be garbage collected when the garbage collector detects that it is unreachable. In your example, the method doesn't put the object reference anywhere else, so it will be unreachable immediately.
Note that even if the object is immediately unreachable, it may take some time for the GC to notice this and collect it. (But that's not a bad thing. It is considerably more efficient to forget the object reference and deal with later than to try to reclaim the space immediately.)
Would it be a problem if I use this kind of method tons of times in my code?
Not necessarily. The example code is not doing anything useful, and hence the overheads of allocating the object and then garbage collected are simply a waste of resources. But if it was doing something useful, the overheads are not likely to be a problem. (In ideal conditions, allocating and garbage collecting an object is cheap in Java.)
Unnecessary allocation can be a problem in some cases though:
If you are running with a heap that is too small for the application's working set of objects, the overheads can ramp up.
HotSpot's default "throughput" GC will "stop the world" while the GC is running, so excessive allocations will increase the number o f GC pauses that you experience. (This may or may not matter ... depending on the application.) You can mitigate this by using CMS or G1 as your collector, but that introduces overheads in other areas.
Assuming the value isn't referenced anywhere else, it will be garbage collected
Will GC collect it?
Yes. Since there would be no live reference to the Object returned it would be eligible for GC.
Would it be a problem if I use this kind of method tons of times in my code?
It should not. All the returned Objects will be GCed.
There's nothing that special about a return value over a local variable, consider:
public Object example {
Object a = new Object();
return new Object();
}
Then if I briefly explain how return values work:
When a method starts a new "stack-frame" is pushed on to the stack. It is an area of memory that includes parameter and local variable storage including the return value. It also knows where to return to.
When the method executes, new objects are created on the heap and only pointers to them exist in the stack.
After the code for the method has been run the value of a non-void return method is passed back to the calling method and stored in it's stack frame.
If a non-void return method's value isn't required by the caller, then it will share the same fate as any other local variable in that stack frame. And that is it's value is no longer used. If that value was an object, then garbage collection is already aware of it and is now able to ascertain that it is not referenced and can be collected.

How to make sure String objects are garbage collected in Java

Here is the code snippet.
method(){
String s1="abc";
String s2 = new String ("abc");
s1=null;
s2=null;
--------
---------
}
At the end is s1 & s2 objects are exists? How you will make sure these objects are garbage collected ?
Objects referenced to by s1 and s2 are eligible for garbage collection once s1=null and s2=null provided that no other references to that Object exists or when the method exits, provided that the Objects were only referenced by the local variables.An object once created uses some memory and the memory remains allocated till there are references for the use of the object.When there are no references for an object, it is assumed to be no longer needed and the memory occupied by the object *can be reclaimed.*An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static refrences in other words you can say that an object becomes eligible for garbage collection if its all references are null.
There are methods like System.gc() and Runtime.gc() which is used to send request of Garbage collection to JVM but it’s not guaranteed that garbage collection will happen. Java programmers can not force Garbage collection in Java; it will only trigger if JVM thinks it needs a garbage collection. Forced GC is sign of bad coding.Once should in turn always look to minimize creation of unnecessary objects and references to those objects.
They get garbage Collected after they go out of scope.
Unless you're actually having serious performance issues, I'd stop worrying about it so much and let the garbage collector do it's thing.
You should be careful though, there are some kinds of elements such as file streams, open sockets, and such that are not managed like that. you have to close those.
If the question is how to make sure, the answer is fairly simple. You can never make sure that any object will be garbage collected. Read this to understand what garbage collection really is and how to reason about it.
If the question is how to hint for a collection, then set all the references of unwanted objects to null and call System.gc(), which will request (not force) a collection. Nothing is guaranteed to be released using this method, but often it's the closest thing you can get.
If you want to do this specifically for strings, because they may contain sensitive data or something along these lines, use a char[] to store that data instead of a String, because you can change the primitive values of the array at will and erase them when you're done.
Garbage collector runs periodically(time period is JVM dependent). Java maintains table of objects and its references when reference is broken (probably by assigning null to reference) then on next execution of GC (garbage collector) object's having no reference will be deleted (If something goes wrong with GC then object will not garbage collected - very very rare condition), which is totally dependent on JVM. You can send request to JVM to run GC by using following code (Processing your request is once again JVM dependent):
Runtime.getRuntime().gc();
or
System.gc();
Programmer don't have to worry about the running GC mostly JVM will handle execution of GC. There are lots of enhancements made to the garbage collectors. Java (latest version) comes with G1(Garbage First) collector which is a server-style garbage collector which runs more effectively. G1 is a great replacement for CMS (Concurrent Mark-Sweep Collector).
If you want to know more about garbage collector then you should read the pages:
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html][1]
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/cms-6.html][2]
[http://docs.oracle.com/javase/7/docs/technotes/guides/vm/par-compaction-6.html][3]
String s2 = new String ("abc");
Here 'abc' will be created in regular, garbage collectible heap area.
So as soon as you make S2 null, this string object is eligible for garbage collection.
This is assuming that your programm do not have any other reference to this particular string object "abc".
String s1="abc";
In this case, "abc" will be created in special area of heap called literal pool or string pool. Making "abc" null does not make "abc" eligible for garbage collection since JVM will try to reuse this "abc" in future.
Baseline in this case is, normal garbage collection rules won't apply here.
Hope this helped. :-)

Java memory questions about 'new' keyword

What happens if you run the following code..
while (true) {
String x = new String("ABC");
}
in terms of memory?
Is String x allocated on the stack or on the heap? Will the program eventually crash because of a memory overflow, or will garbage collection prevent that? Does the new keyword always create the object on the heap? When is an object created on the stack?
Thanks!
Is String x allocated on the stack or on the heap?
x isn't a String. It is a reference to a String. The reference is a local variable, and so goes on the stack. The String is an object, and so goes on the heap.
Will the program eventually crash because of a memory overflow
Probably not.
or will garbage collection prevent that?
It should.
Does the new keyword always create the object on the heap?
Yes.
When is an object created on the stack?
Never ... unless the JVM decides it cannot escape the current scope and so decides to do so.
Using new, yes, puts objects on the heap. Objects that are no longer accessible by any thread can be garbage collected. Whether you run out of memory or not depends on the size of data your program uses, and if you are good at 'releasing' objects you dont need any more (think: memory leaks are bad).
In your example, you will be running the garbage collector like crazy, which I think is what you are intending to demonstrate.
Local variables go on the stack.
In theory, new creates on the Heap, and non-objects (i.e., ints, chars and so on) are created on the stack. The only exception, afaik, are strings, created on the stack as well. In practice, the JIT compiler of many modern JVMs will see that, in some cases, objects created with new can be created on the stack (for example, local objects that are not referenced outside of the current function).
The garbage collector will take care of the deallocation for you, that's its purpose, but of course you can run out of memory if you create and keep references on too many objects at the same time (try creating a list with a billion strings, for example).

What's the difference between SoftReference and WeakReference in Java?

What's the difference between java.lang.ref.WeakReference and java.lang.ref.SoftReference ?
From Understanding Weak References, by Ethan Nicholas:
Weak references
A weak reference, simply put, is a
reference that isn't strong enough to
force an object to remain in memory.
Weak references allow you to leverage
the garbage collector's ability to
determine reachability for you, so you
don't have to do it yourself. You
create a weak reference like this:
WeakReference weakWidget = new WeakReference(widget);
and then
elsewhere in the code you can use
weakWidget.get() to get the actual
Widget object. Of course the weak
reference isn't strong enough to
prevent garbage collection, so you may
find (if there are no strong
references to the widget) that
weakWidget.get() suddenly starts
returning null.
...
Soft references
A soft reference is exactly like a
weak reference, except that it is less
eager to throw away the object to
which it refers. An object which is
only weakly reachable (the strongest
references to it are WeakReferences)
will be discarded at the next garbage
collection cycle, but an object which
is softly reachable will generally
stick around for a while.
SoftReferences aren't required to
behave any differently than
WeakReferences, but in practice softly
reachable objects are generally
retained as long as memory is in
plentiful supply. This makes them an
excellent foundation for a cache, such
as the image cache described above,
since you can let the garbage
collector worry about both how
reachable the objects are (a strongly
reachable object will never be removed
from the cache) and how badly it needs
the memory they are consuming.
And Peter Kessler added in a comment:
The Sun JRE does treat SoftReferences differently from WeakReferences. We attempt to hold on to object referenced by a SoftReference if there isn't pressure on the available memory. One detail: the policy for the "-client" and "-server" JRE's are different: the -client JRE tries to keep your footprint small by preferring to clear SoftReferences rather than expand the heap, whereas the -server JRE tries to keep your performance high by preferring to expand the heap (if possible) rather than clear SoftReferences. One size does not fit all.
Weak references are collected eagerly. If GC finds that an object is
weakly reachable (reachable only through weak references), it'll clear the
weak references to that object immediately. As such, they're good for
keeping a reference to an object for which your program also keeps
(strongly referenced) "associated information" somewere, like cached
reflection information about a class, or a wrapper for an object, etc.
Anything that makes no sense to keep after the object it is associated
with is GC-ed. When the weak reference gets cleared, it gets enqueued in a
reference queue that your code polls somewhere, and it discards the
associated objects as well. That is, you keep extra information about an
object, but that information is not needed once the object it refers to
goes away. Actually, in certain situations you can even subclass
WeakReference and keep the associated extra information about the object
in the fields of the WeakReference subclass. Another typical use of
WeakReference is in conjunction with Maps for keeping canonical instances.
SoftReferences on the other hand are good for caching external, recreatable resources
as the GC typically delays clearing them. It is guaranteed though that all
SoftReferences will get cleared before OutOfMemoryError is thrown, so they
theoretically can't cause an OOME[*].
Typical use case example is keeping a parsed form of a contents from a
file. You'd implement a system where you'd load a file, parse it, and keep
a SoftReference to the root object of the parsed representation. Next time
you need the file, you'll try to retrieve it through the SoftReference. If
you can retrieve it, you spared yourself another load/parse, and if the GC
cleared it in the meantime, you reload it. That way, you utilize free
memory for performance optimization, but don't risk an OOME.
Now for the [*]. Keeping a SoftReference can't cause an OOME in itself. If
on the other hand you mistakenly use SoftReference for a task a WeakReference is meant
to be used (namely, you keep information associated with an Object somehow
strongly referenced, and discard it when the Reference object gets
cleared), you can run into OOME as your code that polls the ReferenceQueue
and discards the associated objects might happen to not run in a timely
fashion.
So, the decision depends on usage
- if you're caching information that is expensive to construct, but
nonetheless reconstructible from other data, use soft references
- if you're keeping a reference to a canonical instance of some data, or
you want to have a reference to an object without "owning" it (thus
preventing it from being GC'd), use a weak reference.
In Java; order from strongest to weakest, there are: Strong, Soft, Weak and Phantom
A Strong reference is a normal reference that protects the referred object from collection by GC. i.e. Never garbage collects.
A Soft reference is eligible for collection by garbage collector, but probably won't be collected until its memory is needed. i.e. garbage collects before OutOfMemoryError.
A Weak reference is a reference that does not protect a referenced object from collection by GC. i.e. garbage collects when no Strong or Soft refs.
A Phantom reference is a reference to an object is phantomly referenced after it has been finalized, but before its allocated memory has been reclaimed.
Source
Analogy: Assume a JVM is a kingdom, Object is a king of the kingdom, and GC is an attacker of the kingdom who tries to kill the king(object).
When King is Strong, GC can not kill him.
When King is Soft, GC attacks him but King rule the kingdom with protection until resource are available.
When King is Weak, GC attacks him but rule the kingdom without protection.
When king is Phantom, GC already killed him but king is available via his soul.
Weak Reference
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
Principle: weak reference is related to garbage collection. Normally, object having one or more reference will not be eligible for garbage collection.
The above principle is not applicable when it is weak reference. If an object has only weak reference with other objects, then its ready for garbage collection.
Let's look at the below example: We have an Map with Objects where Key is reference a object.
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> aMap = new
HashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
System.out.println("Size of Map" + aMap.size());
}
}
Now, during the execution of the program we have made emp = null. The Map holding the key makes no sense here as it is null. In the above situation, the object is not garbage collected.
WeakHashMap
WeakHashMap is one where the entries (key-to-value mappings) will be removed when it is no longer possible to retrieve them from the Map.
Let me show the above example same with WeakHashMap
import java.util.WeakHashMap;
public class Test {
public static void main(String args[]) {
WeakHashMap<Employee, EmployeeVal> aMap =
new WeakHashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
int count = 0;
while (0 != aMap.size()) {
++count;
System.gc();
}
System.out.println("Took " + count
+ " calls to System.gc() to result in weakHashMap size of : "
+ aMap.size());
}
}
Output: Took 20 calls to System.gc() to result in aMap size of : 0.
WeakHashMap has only weak references to the keys, not strong references like other Map classes. There are situations which you have to take care when the value or key is strongly referenced though you have used WeakHashMap. This can avoided by wrapping the object in a WeakReference.
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> map =
new HashMap<Employee, EmployeeVal>();
WeakReference<HashMap<Employee, EmployeeVal>> aMap =
new WeakReference<HashMap<Employee, EmployeeVal>>(
map);
map = null;
while (null != aMap.get()) {
aMap.get().put(new Employee("Vinoth"),
new EmployeeVal("Programmer"));
System.out.println("Size of aMap " + aMap.get().size());
System.gc();
}
System.out.println("Its garbage collected");
}
}
Soft References.
Soft Reference is slightly stronger that weak reference. Soft reference allows for garbage collection, but begs the garbage collector to clear it only if there is no other option.
The garbage collector does not aggressively collect softly reachable objects the way it does with weakly reachable ones -- instead it only collects softly reachable objects if it really "needs" the memory. Soft references are a way of saying to the garbage collector, "As long as memory isn't too tight, I'd like to keep this object around. But if memory gets really tight, go ahead and collect it and I'll deal with that." The garbage collector is required to clear all soft references before it can throw OutOfMemoryError.
The only real difference between a soft reference and a weak reference is that
the garbage collector uses algorithms to decide whether or not to
reclaim a softly reachable object, but always reclaims a weakly
reachable object.
SoftReference is designed for caches. When it is found that a WeakReference references an otherwise unreachable object, then it will get cleared immediately. SoftReference may be left as is. Typically there is some algorithm relating to the amount of free memory and the time last used to determine whether it should be cleared. The current Sun algorithm is to clear the reference if it has not been used in as many seconds as there are megabytes of memory free on the Java heap (configurable, server HotSpot checks against maximum possible heap as set by -Xmx). SoftReferences will be cleared before OutOfMemoryError is thrown, unless otherwise reachable.
This article can be super helpful to understand strong, soft, weak and phantom references.
To give you a summary,
If you only have weak references to an object (with no strong references), then the object will be reclaimed by GC in the very next GC cycle.
If you only have soft references to an object (with no strong references), then the object will be reclaimed by GC only when JVM runs out of memory.
So you can say that, strong references have ultimate power (can never be collected by GC)
Soft references are powerful than weak references (as they can escape GC cycle until JVM runs out of memory)
Weak references are even less powerful than soft references (as they cannot excape any GC cycle and will be reclaimed if object have no other strong reference).
Restaurant Analogy
Waiter - GC
You - Object in heap
Restaurant area/space - Heap space
New Customer - New object that wants table in restaurant
Now if you are a strong customer (analogous to strong reference), then even if a new customer comes in the restaurant or what so ever happnes, you will never leave your table (the memory area on heap). The waiter has no right to tell you (or even request you) to leave the restaurant.
If you are a soft customer (analogous to soft reference), then if a new customer comes in the restaurant, the waiter will not ask you to leave the table unless there is no other empty table left to accomodate the new customer. (In other words the waiter will ask you to leave the table only if a new customer steps in and there is no other table left for this new customer)
If you are a weak customer (analogous to weak reference), then waiter, at his will, can (at any point of time) ask you to leave the restaurant :P
The six types of object reachability states in Java:
Strongly reachable objects - GC will not collect (reclaim the memory occupied by) this kind of object. These are reachable via a root node or another strongly reachable object (i.e. via local variables, class variables, instance variables, etc.)
Softly reachable objects - GC may attempt to collect this kind of object depending on memory contention. These are reachable from the root via one or more soft reference objects
Weakly reachable objects - GC must collect this kind of object. These
are reachable from the root via one or more weak reference objects
Resurrect-able objects - GC is already in the process of collecting these objects. But they may go back to one of the states - Strong/Soft/Weak by the execution of some finalizer
Phantomly reachable object - GC is already in the process of collecting these objects and has determined to not be resurrect-able by any finalizer (if it declares a finalize() method itself, then its finalizer will have been run). These are reachable from the root via one or more phantom reference objects
Unreachable object - An object is neither strongly, softly, weakly, nor phantom reachable, and is not resurrectable. These objects are ready for reclamation
For more details: https://www.artima.com/insidejvm/ed2/gc16.html « collapse
The Only Real Difference
Per the doc, loose WeakReferences must be cleared by a running GC.
Per the doc, loose SoftReferences must be cleared before OOM is thrown.
That's the only real difference. Everything else is not part of the contract. (I'll assume the latest docs are contractual.)
SoftReferences are useful. Memory-sensitive caches use SoftReferences, not WeakReferences.
The only proper use of WeakReference is to observe the GC run. You do this by creating a new WeakReference whose object immediately goes out of scope, then try to get null out of weak_ref.get(). When it's null, you learn that between this duration, the GC ran.
As for incorrect use of WeakReference, the list is endless:
a lousy hack to implement priority-2 softreference such that you don't have to write one, yet it doesn't work as expected because the cache would be cleared on every GC run, even when there is spare memory. See https://stackoverflow.com/a/3243242/632951 for phails. (Besides, what if you need more than 2 levels of cache priority? You'd still gotta need a real library for it.)
a lousy hack to associate data with an object of an existing class, yet it creates a memory leak (OutOfMemoryError) when your GC decides to take a break after your weakreferences are created. Besides, it's beyond ugly: A better approach is to use tuples.
a lousy hack to associate data with an object of an existing class, where the class has the nerve to make itself non-subclassable, and is used in an existing function code which you need to call. In such a case, the proper solution is to either edit the class and make it subclassable, or edit the function and make it take an interface instead of a class, or use an alternative function.
To give an in-action memory usage aspect, I did an experiment with Strong, Soft, Weak & Phantom references under heavy load with heavy objects by retaining them till end of program. Then monitored heap usage & GC behavior. These metrics may vary case by case basis but surely gives high level understanding. Below are findings.
Heap & GC Behavior under heavy load
Strong/Hard Reference - As program continued, JVM couldn't collect retained strong referenced object. Eventually ended up in "java.lang.OutOfMemoryError: Java heap space"
Soft Reference - As program continued, heap usage kept growing, but OLD gen GC happened hen it was nearing max heap. GC started bit later in time after starting program.
Weak Reference - As program started, objects started finalizing & getting collected almost immediately. Mostly objects got collected in young generation garbage collection.
Phantom Reference - Similar to weak reference, phantom referenced objects also started getting finalized & garbage collected immediately. There were no old generation GC & all objects were getting collected in young generation garbage collection itself.
You can get more in depth graphs, stats, observations for this experiment here.
One should be aware that a weakly referenced object will only get collected when it has ONLY weak reference(s). If it has so much as one strong reference, it does not get collected no matter how many weak references it has.
WeakReference: objects that are only weakly referenced are collected at every GC cycle (minor or full).
SoftReference: when objects that are only softly referenced are collected depends on:
-XX:SoftRefLRUPolicyMSPerMB=N flag (default value is 1000, aka 1 second)
Amount of free memory in the heap.
Example:
heap has 10MB of free space (after full GC);
-XX:SoftRefLRUPolicyMSPerMB=1000
Then object which is referenced only by SoftReference will be collected if last time when it was accessed is greater then 10 seconds.

Categories

Resources