Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About memory leaks and generic methods

Which of these is better to use in my app?

public class NetworkCheck {

    Context context;

    public NetworkCheck(Context context) {
        this.context=context;
    }

    public boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo() != null;
    }
}

...    

if(new NetworkCheck(this).isNetworkConnected()){
    //statement
}

For the above one I have to create heap memory every time whenever I have to use its method. Its heap memory will be destroyed when its scope ends (means end of curly braces)...

Alternatively.

public class NetworkCheck {

    public static boolean isNetworkConnected(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo() != null;
    }
}

...

if(NetworkCheck.isNetworkConnected(){
    //statement
}

For this one I don't have to create any heap memory. I read many articles where people are saying creating a static variable and method causes a memory leak in the application.

and please help me to c create this Genric getLocalData() of the below method .....

 public static <T> void saveLocalData(Context context, String key, T value) {
        SharedPreferences prefs = context.getSharedPreferences(
                "Qikqrup", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        if (value instanceof String)
            editor.putString(key, (String) value);
        else if (value instanceof Boolean)
            editor.putBoolean(key, (Boolean) value);
        else if (value instanceof Integer)
            editor.putInt(key, (Integer) value);
        editor.commit();
    }
like image 967
sushildlh Avatar asked Dec 03 '22 23:12

sushildlh


2 Answers

The second case cannot be beaten, as it is tightest.

In the first case as long as the NetworkCheck object lives, the Context object will be kept alive. And there is a second object (NetworkCheck).

However:

  • its use is limited and the object will rapidly go out of scope and be garbage collected. So the effect is as remarkable as the spontaneous creation of particle and antiparticle around us.
  • In other cases the separation of constructor and call, maybe many calls might prove usefull.

About:

public static <T> void saveLocalData(Context context, String key, T value)

Not usefull, Object would be better. In fact null will not be catched. In general this function has a partial domain: not all classes will do. And again retrieving the value will be guess work.

Using run-time information might do.

public static <T> void saveLocalData(Context context, String key, Class<T> type, T value)
public static <T> T loadLocalData(Context context, String key, Class<T> type)

Java has a Serializable interface that can be used too.

public static <T> void saveLocalData(Context context, String key, Serializable value)

Then you receive the object back as you stored it. You will need to read up on the subject.

like image 51
Joop Eggen Avatar answered Jan 01 '23 01:01

Joop Eggen


In your saveLocalData() method, there isn't necessarily a memory leak, but there can be a memory leak, depending on how you use it. For example, take this:

for( long i = 0;  i < Long.MAX_VALUE;  i++ )
{
    String name = String.valueOf( i );
    saveLocalData( context, name, i );
}

This loop will keep adding values to your map until you run out of memory. But the same can happen with any collection, not just with maps, and it can happen whether your collection is statically allocated or not. With a static collection it is just slightly easier to happen than with a non-static collection, because presumably the non-static collection could conceivably go out of scope and be garbage collected, while the static collection is usually destined to stay forever.

However, there is nothing absolute about this statement:

  • On one hand, a non-static collection may very easily be permanently anchored to memory by being referenced by an object which is static, while:

  • On the other hand, a static map may be explicitly freed and reallocated or simply cleared by a careful programmer who does not want it to grow too big.


In order to write getLocalData() you need to declare it as follows:

public static <T> T getLocalData( Context context, String key, Class<T> classOfValue )

And invoke it as follows:

String name = MyClass.getLocalData( context, "Name", String.class );

within the function, you are going to need to do something like this:

if( classOfValue == String.class )
    return editor.getString( key );
...

Your two versions of NetworkCheck and your intended usage of each is roughly equivalent to each other, there is not much to gain or loose between choosing one or the other. Doing new NetworkCheck(this) represents a redundant memory allocation, but as you already understand, this memory gets garbage-collected very quickly, so there is no damage.

like image 36
Mike Nakis Avatar answered Jan 01 '23 01:01

Mike Nakis