Memory leak if we create HashMap object multiple times - java

public class TestProcessor{
public void fillData(){
boolean success = true;
HashMap<String,String> hMap = null;
if (success){
hMap = new HashMap<String,String>();
hMap.put("one","java");
hMap.put("two","servlet");
}
if(hMap! = null){
processData(hMap);
}
}
public void processData(HashMap<String,String> map){
String param1 = map.get("one");
String param2 = map.get("two");
}
}
In the above code if we call fillData() method multiple times and the if condition becomes true then HashMap object will be created multiple times.Will this cause Memory Leak problem?If memory leak happens then how can we fix it?

The Java Virtual Machine (JVM) actively and automatically manages the memory your application uses. Some things to keep in mind about Java's memory management:
Memory is automatically allocated in heap memory for objects that your program creates.
When an object can no longer be accessed by your program (usually by falling out of scope so that no variables that reference the object can be accessed) the memory is automatically reclaimed by a process called garbage collection.
Garbage collection is automatic and non-deterministic. Your program can't know (or predict) when garbage collection is going to occur (so you don't know exactly when unreachable objects will be reclaimed).
In the majority of cases, the JVM manages memory so well that no memory leaks occur even when a program runs for a long time (and creates and reclaims many objects).
By the above reasoning, the code snippet you show will not result in any memory leaks. There are only a few situations in which memory leaks will occur in Java:
1. When you do your own memory management. Memory leaks can occur if you implement your own data structures for objects. For example, if you create your own stack implementation, objects that are "popped" out of your stack can still have active references to them. When this happens, the object will not be garbage collected even if it is no longer in the active portion of your stack. This is one of the few cases in which it can be important to actively assign null to elements that may refer to objects that are no longer "being used."
2. Any time you have a long-lived object that holds a reference to an object that you intend to be short lived. The most common situation in which this can cause memory leaks is in the use of non-static inner classes and anonymous classes (both of which contain a reference to their enclosing instance).
Every non-static Inner Class has an implicit reference to its surrounding class. Anonymous Classes are similar. To successfully create a memory leak simply pass an Inner Class object to a method which keeps references to the provided objects and you're done.
Why does this cause a memory leak? Suppose you implement something like a cache. Next follow the execution path to a local object which stores some of its inner class objects into the cache. After the local object was out of scope, it won't be garbage collected anymore! The inner class object in the cache holds a reference to the surrounding object and that one is still referenceable and therefore not a candidate for garbage collection anymore. The same is true for anonymous classes!

It should not create a memory leak as you will be replacing your existing hashmap which would allow the old one to be garbage collected.
If you are holding references to the objects within in the hashmap externally, then you may cause them to be retained.
*I'm assuming this is java from your syntax.

Related

Does JVM garbage collect objects being referenced by local variables which are no longer used? [duplicate]

This question already has answers here:
Can java finalize an object when it is still in scope?
(2 answers)
Closed 3 years ago.
As far as I know, a method's local variable is located in a stack frame in an executing thread and a reference type of a local variable only has a objects' reference, not the object itself. All of objects in JVM are located in a heap space.
I want to know that objects referenced by local variables in a method being executed are never garbage collected until the end of the method execution. (without using java.lang.ref.WeakReference and SoftReference.)
Are they garbage collected? or never? Is there compiler's optimization to this type of stuff?
(If they are never garbage collected, this means it may be needed to assign null to variables no longer used when executing big methods which take long time.)
As elaborated in Can java finalize an object when it is still in scope?, local variables do not prevent the garbage collection of referenced objects. Or, as this answer puts it, scope is a only a language concept, irrelevant to the garbage collector.
I’ll cite the relevant part of the specification, JLS §12.6.1 again:
A reachable object is any object that can be accessed in any potential continuing computation from any live thread.
Further, I extended the answer’s example to
class A {
static volatile boolean finalized;
Object b = new Object() {
#Override protected void finalize() {
System.out.println(this + " was finalized!");
finalized = true;
}
#Override public String toString() {
return "B#"+Integer.toHexString(hashCode());
}
};
#Override protected void finalize() {
System.out.println(this + " was finalized!");
}
#Override public String toString() {
return super.toString() + " with "+b;
}
public static void main(String[] args) {
A a = new A();
System.out.println("Created " + a);
for(int i = 0; !finalized; i++) {
if (i % 1_000_000 == 0)
System.gc();
}
System.out.println("finalized");
}
}
Created A#59a6e353 with B#6aaa5eb0
B#6aaa5eb0 was finalized!
finalized
A#59a6e353 with B#6aaa5eb0 was finalized!
which demonstrates that even the method with the variable in scope may detect the finalization of the referenced object. Further, being referenced from a heap variable doesn’t necessarily prevent the garbage collection either, as the B object is unreachable, as no continuing computation can access it when the object containing the reference is unreachable too.
It’s worth emphasizing that even using the object does not always prevent its garbage collection. What matters, is whether the object’s memory is needed for the ongoing operation(s) and not every access to an object’s field in source code has to lead to an actual memory access at runtime. The specification states:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. […]
Another example of this occurs if the values in an object's fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage.
This is not only a theoretical option. As discussed in finalize() called on strongly reachable object in Java 8, it may even happen to objects while a method is invoked on them, or in other words, the this reference may get garbage collected while an instance method is still executing.
The only ways to prevent an objects garbage collection for sure, are synchronization on the object if the finalizer also does synchronization on the object or calling Reference.reachabilityFence(object), a method added in Java 9. The late addition of the fence method demonstrates the impact of the optimizers getting better from version to version on the issue of earlier-than-wanted garbage collection. Of course, the preferred solution is to write code that does not depend on the time of garbage collection at all.
It is not quite true that all of the objects are in heap space; but it is generally true. Java has been extended to have stack-local objects, provided the JVM can detect that the object will live only as long as the stack frame.
Now for the objects on the heap, which have a local reference in a method. While the method is being processed, the stack frame associated with the method run contains the local variable references. As long as the reference can be used (which includes being still in the stack frame) the object will not be garbage collected.
Once the reference has been destroyed, and the object can no longer be reached by the running program (because there's no references that can reach it), then the garbage collector will collect it.

Does a static field outlive the containing instance? Is this a memory leak?

I am using a library as part of my application.
I am instantiating a class that is imported from this library. E.g. Calculator c = new Calculator() and use the instance.
The class Calculator has a static member field which is a hash map internalMap with strong references to objects. I am referring to the key/value pairs.
So while I use the instance c this static internalMap is getting populated (by the internal logic of this library not by my code).
What I am not sure about is whether this static hashmap outlives the instance.
I think that if c is GCed the static internalMap will not be GCed because it is static.
So essentially this memory is being "lost"? I.e a memory leak?
The short answer is yes. You will have to clean up any statics you have if you want to reclaim that memory. Perhaps the author of the library has already provided some way of handling this?
As far as I know, the GC (Garbage Collector) looks at heap memory and identify which objects are in use (and which are not)...deleting the unused objects. If an object is being used/referenced, it means that "somebody" still maintains a pointer to it. On the other hand, an unused/unreferenced object that's no longer referenced, it's ready to release the memory used when the GC runs.
Based on that, for your Calculator class, whenever you have references in the internalMap and the GC runs, it won't be released...at all. So it's not that "it outlives the instance", the instance will be there until it gets GC'ed, but because it still has a (or more) member(s) that has some "active" references it cannot be GC'ed (thus, the memory occupied by it cannot be reused/freed).
Correct me if I'm wrong...

Replacing Java Objects at runtime

The below class is initialised on the init() method of a servlet.
objA is only used for reading, the refreshA-method needs to be called periodically to replace it with a new instance of A.
The problem :
After periodical updates, a memory leak appears. (I am guessing there are some dangling references multiple copies of the A existing)
public Class A {
private static volatile A objA;
public static A getA(){
if(objA == null){
synchronized (A.class){
if(objA == null){
objA = new A(); //takes a long time to initialise and memory heavy
return objA;
}
}
}
return objA;
}
public static void refreshA (A newObjA){
// best way to do this ?
/*
objA = newObjA;
*/
}
}
Kind of hacky :
I could use
ConcurrentHashMap<String,A> -> get("OBJ-A"), replace("OBJ-A", newObjA)
this would use the ReentrantReadWriteLock but I havent tried it yet.
So what would be the best way to implement refreshA()? Keeping in mind that the GC should remove the old reference.
First of all, double-checked locking is not recommended
, see en.wikipedia.org/wiki/Double-checked_locking.
As for the replacable field, you can use an AtomicReference.
And regarding the memory leak, consider giving out a proxy to the actual object. This way you can swap out the backing instance and be sure that noone keeps a reference to the old backing object.
It looks like you have figured out how to (re-)implement the singleton and the refresh operation.
I want to focus on some of the other things in your Question.
(Pure) Java cannot have dangling references. The values in any reference in any live object in Java will either be null or valid reference to an existing object. This even applies to unreachable objects.
Dangle references (i.e. pointers that no longer point to a valid object) don't cause storage leaks. Rather they are a sign of heap corruption. In Java, if the JVM (including the GC) attempted to use a dangling reference, the result would most likely be a hard crash.
If is not entirely clear what you think the connection between the memory leak and your periodic update is. However:
The periodic update is almost certainly not the cause of this memory leak. Certainly it is not, on the evidence of the code you have shown us.
A periodic update is not guaranteed to cure a memory leak, unless the A static holds the one and only long-term reference to the A instance that is leaking. Indeed, if you "refresh" the A singleton in this way, there is a distinct possibility that you will cause a leak. For example, if some other code calls the getA() method and caches the result somewhere, when A.refreshA() is called you will end up with TWO A instances in existence, and the first one has effectively leaked.
Finally your refresh operation is breaking the implicit singleton semantics of A. That could cause all sorts of other problems, including threading issues.
If you suspect that your A class is the cause of a memory leak, then a better approach to fixing the problem is to:
figure out what part of A's state is the dangerous part of the leak, and
add a synchronized instance method to A to clear that state.
Note that not all leaks are harmful. An object that exists for the lifetime of the application (e.g. a static) could appear to be a leak (to a leak detector) but is not going to cause any problems.

Java Assignment Memory Leaks

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 .

Does variable = null set it for garbage collection

Help me settle a dispute with a coworker:
Does setting a variable or collection to null in Java aid in garbage collection and reducing memory usage? If I have a long running program and each function may be iteratively called (potentially thousands of times): Does setting all the variables in it to null before returning a value to the parent function help reduce heap size/memory usage?
That's old performance lore. It was true back in 1.0 days, but the compiler and the JVM have been improved to eliminate the need (if ever there was one). This excellent IBM article gets into the details if you're interested: Java theory and practice: Garbage collection and performance
From the article:
There is one case where the use of explicit nulling is not only helpful, but virtually required, and that is where a reference to an object is scoped more broadly than it is used or considered valid by the program's specification. This includes cases such as using a static or instance field to store a reference to a temporary buffer, rather than a local variable, or using an array to store references that may remain reachable by the runtime but not by the implied semantics of the program.
Translation: "explicitly null" persistent objects that are no longer needed. (If you want. "Virtually required" too strong a statement?)
The Java VM Spec
12.6.1 Implementing Finalization
Every object can be characterized by two attributes: it may be reachable, finalizer-reachable, or unreachable, and it may also be unfinalized, finalizable, or finalized.
A reachable object is any object that can be accessed in any potential continuing computation from any live thread. Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
Discussion
Another example of this occurs if the values in an object's fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage.
The object is reachable if it can be involved in any potential continuing computation. So if your code refers to a local variable, and nothing else refers to it, then you might cause the object to be collected by setting it to null. This would either give a null pointer exception, or change the behaviour of your program, or if it does neither you didn't need the variable in the first place.
If you are nulling out a field or an array element, then that can possibly make sense for some applications, and it will cause the memory to be reclaimed faster. Once case is creating a large array to replace an existing array referenced by a field in a class - if the field in nulled before the replacement is created, then it may relieve pressure on the memory.
Another interesting feature of Java is that scope doesn't appear in class files, so scope is not relevant to reachability; these two methods create the same bytecode, and hence the VM does not see the scope of the created object at all:
static void withBlock () {
int x = 1;
{
Object a = new Object();
}
System.out.println(x+1);
}
static void withoutBlock () {
int x = 1;
Object a = new Object();
System.out.println(x+1);
}
Not necessarily. An object becomes eligible for garbage collection when there are no live threads anymore that hold a reference to the object.
Local variables go out of scope when the method returns and it makes no sense at all to set local variables to null - the variables disappear anyway, and if there's nothing else that holds a reference the objects that the variables referred to, then those objects become eligible for garbage collection.
The key is not to look at just variables, but look at the objects that those variables refer to, and find out where those objects are referenced by your program.
It is useless on local variables, but it can be useful/needed to clear up instance variables that are not required anymore (e.g. post-initialization).
(Yeah yeah, I know how to apply the Builder pattern...)
That could only make some sense in some scenario like this:
public void myHeavyMethod() {
List hugeList = loadHugeListOfStuff(); // lots of memory used
ResultX res = processHugeList(hugeList); // compute some result or summary
// hugeList = null; // we are done with hugeList
...
// do a lot of other things that takes a LOT of time (seconds?)
// and which do not require hugeList
...
}
Here it could make some benefit to uncomment the hugeList = null line, I guess.
But it would certainly make more sense to rewrite the method (perhaps refactoring into two,
or specifying an inner scope).
Setting an object reference to null only makes it eligible for garbage collection.
It does not necessarily free up the memory,which depends on when the garbage collector runs(which depends on JVM).
When the garbage collector runs,it frees up the heap by deleting only the objects which are eligible for garbage collection.
It is a good to have. When you set objects to null, there is a possibility that the object can be garbage collected faster, in the immediate GC cycle. But there is no guaranteed mechanism to make an object garbage collected at a given time.

Categories

Resources