Furkan Yurdakul
Furkan Yurdakul

Reputation: 3157

Possible memory leaks on inner final object (Java)

I have searched through these occasions a little bit and couldn't find a satisfying answer, so here I am. Note: This is going to be an example code, as I cannot post anything from the original code since it is classified.

Suppose this occasion:

public class Instance
{
    private ClassMember classMember = new ClassMember();

    // Imagine this method is called once as like the main method of apps.
    public static void main(String[] args)
    {
        new Instance().myMethod();
    }

    private void myMethod()
    {
        final SomeObject object = new SomeObject();

        // This is the class member that is declared at top of the class.
        classMember.addCallback(new Callback()
        {
            @Override
            public void onCall(boolean result)
            {
                object.setResult(result).report(); // I'm done with this object, want to release it.

                // After this call, will there be a leak due to "SomeObject object"?
                // If so, how can this be prevented from happening?
            }
        });

        object.makeCall(classMember); // asynchronous task such as Internet connections.
    }
}

Let's explain variables and classes:

Now, what I wonder is, there might be a memory leak due to "final SomeObject object" and I want to prevent it by releasing it after receiving the callback at "onCall()" method, such as setting it to null. But because it is final, I cannot do that, hence I'm looking for an alternative.

Any suggestions? Thanks.

Upvotes: 1

Views: 94

Answers (2)

dpr
dpr

Reputation: 10964

Given the provided code there is no memory leak due to someObject it being final or not. The instance is only used within the scope of myMethod and no reference is given to the outside (at least outside of Instance). That is the GC will notice that it can be collected after myMethod or the asynchronous makeCall have finished.

The only thing I‘m worried about is that you mention the call to makeCall might not finish at all. You have to keep in mind that all resources in the context of this call will be uncollectable until the call has finished. That is the instances of Instance, ClassMember and SomeObject will remain on the heap for the duration of makeCall.

Of course if you do something stupid in makeCall you will get a leak the one way or the other.

UPDATE:

As @Seelenvirtuose pointed out your example code may be a little oversimplified, resulting to false assumptions being made. My answer is correct as long as the instances of Instance are used in the way they are used in the provided code - as one-shot-obects. You have to be aware that with each call to myMethod and each call to classMember.addCallback, classMember will get a reference to the object instance created in myMethod. That is references to object will accumulate in classMember and thus in the respective instance of Instance - that's what I meant with my addition at least outside of Instance. Given the provided code you might end up with a memory leak or not. It all depends on the usage of Instance in your real world scenario.

Upvotes: 1

M.F
M.F

Reputation: 443

The final state will not prevent it from garbage collection. If the callback is executed and object is not held within classMember (due to some handler list or sth. like this) the reference counter decreases to 0 and thus it will be garbage collected (at some time).

Upvotes: -1

Related Questions