0

If I have a Helper Class like the following:

public class TestHelper {
  private Context context;

  public TestHelper(Context context);
    this.context = context;
  }

  public doSomethingWithContext(){
    //some code
   }

and my Activity looks like the following:

 public class MainActivity extends AppCompatActivity{
  private TestHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       helper = new TestHelper(this);
    }

 }

Will the context be leaked like this or do I have to set helper to null in the onDestroy method (would this even work for the GC)?

Also I need the helper in several methods (onCreate, onPause etc) so creating the Helper inside in all of the methods doesn't sound like a good solution.

Shirish Herwade
  • 11,461
  • 20
  • 72
  • 111
akdeniza
  • 33
  • 4
  • This excact code will not cause the activity leak ... – Selvin Dec 07 '16 at 10:22
  • 2
    Yes, if your saving the context in the helper class, it will leak your context. It will not garbage collected. Never do dereference on onDestroy, because it will not guaranteed to be called. You can set the null on onStop instead. – HendraWD Dec 07 '16 at 10:22
  • @HendraWD what leak ... this code (the code from the question) will not cause any leak ... context in helper class is not used and helper class instance is a field in activity itself ... so it will "die" with an activity ... **but if he would use the context in helper class then setting helper instance to null may not be enough to avoid activity leaks** – Selvin Dec 07 '16 at 10:24
  • @akdeniza It depends on what you are doing in helper class ... fx if you would change `private Context context;` to `private static Context context;` it would cause activity leak and setting instance in onStop would not help ... – Selvin Dec 07 '16 at 10:34
  • Edited the question a bit and added the method doSomethingWithContext(). Would it leak this way? Looking at this image: https://i.stack.imgur.com/SZh5r.png it looks like if I set in the onDestroy method the helper to be null it shouldn't lead to any leaks? – akdeniza Dec 07 '16 at 10:38
  • again, it depends what is done with context in doSomethingWithContext – Selvin Dec 07 '16 at 10:39
  • Sorry what i mean here is Singleton pattern that save the context. I need to be more thorough next time. I have checked again, and there will be no problem with your code. – HendraWD Dec 07 '16 at 10:41
  • @Selvin Please post a seperate answer so I can mark your reply as answer – akdeniza Dec 08 '16 at 09:27

2 Answers2

1

Context doesn't leak in your code because GC correctly handles cyclic references. See explanation here

Community
  • 1
  • 1
pitfall
  • 166
  • 1
  • 4
-1

Garbage collector only dereference primitive or builtin data types. If you have custom objects in your code like custom class or in this case Context you have to manually dereference to avoid memory leaks

Example:

public class TestHelper {

  private List<String> items = new ArrayList<>();
  private float floatValue = 0;
  private String stringValue = "";

}

When you initialize TestHelper testHelper = new TestHelper();. System will allocate a memory for your testHelper object. Each object like items, floatValue and stringValue has a separate memory locations but somehow composed in testHelper reference.

float and String are primitive data types, whereas List<String> is not. So now when you do testHelper = null; it will dereference float and String but not List<String>. To do so you have to call items.clear();and then call items = null;.

For more details clearing or set null to objects in java

Community
  • 1
  • 1
Haris Qurashi
  • 2,104
  • 1
  • 13
  • 28
  • *To do so you have to call items.clear();and then call items = null;* ... this is not true ... `testHelper = null;` is good enough ... as List items would be unreachable from any root – Selvin Dec 07 '16 at 11:40
  • The link that you had provide has nothing to do with an example from your answer ... – Selvin Dec 07 '16 at 14:05
  • http://ideone.com/tTmgb0 ther is no single `items.clear()` nor `items = null;` only `helper = null;` but memory is at the same level ... if you do `//uncomment this to keep the references` then you will see that memory increase and then after `array = null;` is lowered to initial state ... all: *So now when you do testHelper = null; it will dereference float and String but not List. To do so you have to call items.clear();and then call items = null;* **is not true** – Selvin Dec 07 '16 at 14:32