-1

I have following code:

public void method1() {
    Emp e1 = new Emp();
    Emp e2 = new Emp():
    Emp e3 = new Emp();
    method2(e1, e2, e3);
}

public void method2(Emp... emps) {
    List<Emp> emps = new ArrayList<>();
    for(final Emp emp : emps) {
        emps.add(emp);
    }
    // do some task with list
}

So when method2 returns will emps be garbage collected? Or we need to explicitly remove elements. Would like to understand in perspective of memory leaks.

Any pointers appreciated greatly.

Ganesh Shenoy
  • 619
  • 1
  • 10
  • 28
  • This won't compile. – shmosel Sep 17 '18 at 22:46
  • 5
    *"when method2 returns will emps be garbage collected?"* Pedantic answer: Unlikely, since GC probably won't run for quite some time. `emps` will be *eligible* for GC when `method2` returns, but the actual act of GC won't happen until the JVM chooses to do so, and you have no idea when that might be. --- Also, only `emps` is eligible for GC when `method2` returns. The 3 `Emp` objects are still referenced by the local variables in `method1`, so they are not eligible for GC until `method1` returns too. – Andreas Sep 17 '18 at 22:56
  • You do not have any Singletons in your code example, yet mentioned in your title. Edit either your title or body to match each other. – Basil Bourque Sep 17 '18 at 23:53
  • Side note: to get a `List` from the varargs parameter, just use `List empsList = Array.asList(emps);` – Holger Sep 18 '18 at 06:51

2 Answers2

2

There is no definite time when garbage collection will run. Whenever there is no reference to an object it will become eligible for garbage collection.

When a method is called in Java it goes inside the stack frame. When the method is popped from the stack, all its members die. Hence they become eligible for gc. The objects that were created inside it becomes unreachable or anonymous after method execution and thus becomes eligible for garbage collection.

Pritam Banerjee
  • 17,953
  • 10
  • 93
  • 108
  • 1
    Indeed, there is no guarantee garbage collection *ever* happens at all. If your app is short-lived with lots of memory allocated, the collector may not need to run before exiting. Or your app might be running with the new [*Epsilon: A No-Op Garbage Collector*](http://openjdk.java.net/jeps/318) that does not implement any actual memory reclamation mechanism. Furthermore, with the new [*Garbage Collector interface*](http://openjdk.java.net/jeps/304) in Java 10 and later, we may see even more varied behaviors in future collectors. – Basil Bourque Sep 17 '18 at 23:54
1

Short answer: Yes, "emps" will be Garbage Collected, and No, you do not need to explicitly remove elements in Java.

Longer answer: Assuming you are new to Java and Garbage Collection (maybe coming from a C++ background?) then the answers so far may be skipping the very simple answer you are looking for. As some have pointed out, your posted code would not quite compile in Java, so we can't quite give a perfect answer. That said, I assume you are really just asking whether we have to explicitly free memory in Java: No, we do not.

From Java Garbage Collection Basics:

In a programming language like C, allocating and deallocating memory is a manual process. In Java, (the) process of deallocating memory is handled automatically by the garbage collector.

Garbage Collection is a complicated topic, but you can essentially trust that the JVM will identify "which objects are in use and which are not" on some interval, and will delete "the unused objects" on some interval. Therefore, you will likely not open up any "memory leaks" in your program if you allow the JVM to see that objects are unused -- in other words, don't hold onto objects when you don't need them.

Design.Garden
  • 3,607
  • 25
  • 21
  • Marking *unused* objects won't really happen - pretty every GC works the other way round: It rescues the non-garbage and what's left behind is free memory. – maaartinus Sep 18 '18 at 06:33
  • "The first step in the process is called marking. This is where the garbage collector identifies which pieces of memory are in use and which are not."(https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html). What edit are you suggesting to my post? – Design.Garden Sep 18 '18 at 19:56
  • What gets marked are the *objects in use*, not the other way round. This has two reasons: 1. There's no way to mark *objects not in use* as they can't be reached (there's no central directory of all objects; there are so called GC roots, from whom you start and mark everything reachable as live). 2. The count of dead objects is usually much bigger than the count of surviving objects, so not touching dead objects is essential for efficiency. Actually, there are many different GCs and this makes it more complicated. +++ No idea how to formulate it better. Maybe just replace "marked" by "unused". – maaartinus Sep 18 '18 at 20:55
  • 1
    @maaartinus, I've removed references to "marking", and I've replaced some of my own phrasing with direct quotes. – Design.Garden Sep 19 '18 at 01:31