0

I tried to break it down to the main code regarding the pix array:

public class BitmapProcessor {
    int[] pix;

    public Bitmap run(Bitmap b)
    {
        pix = new int[picw * pich];
        bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
        // do some stuff
        bm = Bitmap.createBitmap(picw, pich, Bitmap.Config.ARGB_8888);
        bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
        pix = null;
        return bm;
    }
}

After this I still see pix in the monitor. Even if I click on Cause GC. Is the array being referenced inside the bitmap or why does it still exist?

PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
  • 2
    It is a very common misunderstanding to think that setting things to `null` actually makes the GC free the memory. This leads to the question why `pix` is not a local variable in your case? That would make it "go away" when the scope of the method is left. – Thorsten Dittmar Jun 15 '15 at 11:21
  • I got that idea from SO. See http://stackoverflow.com/questions/2974251/free-memory-of-a-byte-array-in-java – PiTheNumber Jun 15 '15 at 11:22
  • 1
    Even by forcing GC it may not free resources. Not the way. Maybe if you instance couple dozens for those int arrays and then GC some may die. – eduyayo Jun 15 '15 at 11:23
  • 1
    The garbage collector will free the memory in its own time. Its designed to not interfere with your running program and to perform the clean up in the most efficient way possible. That means it will attempt to clean up a lot at once rather than cleaning every time you set something null. – Philip Couling Jun 15 '15 at 11:23

2 Answers2

1

You have declared int[] pix to be an instance variable. So when an object of this class will be created a copy of pix variable will be created in memory and it will remain in memory till the object lasts.

In your case you can declare int[] pix to be local variable of method.

public class BitmapProcessor {


    public Bitmap run(Bitmap b)
    {
        int[] pix = new int[picw * pich];
        bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
        // do some stuff
        bm = Bitmap.createBitmap(picw, pich, Bitmap.Config.ARGB_8888);
        bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
        return bm;
    }
}

So it will be GCed when method operation finishes.

gprathour
  • 14,813
  • 5
  • 66
  • 90
  • 3
    @GPRathour, it will be recycled by the runtime but may not be GC'd instantly. Only when that memory is claimed, needed again or the garbage collector decides to recycle, pack or whatever. – eduyayo Jun 15 '15 at 11:25
  • @eduyayo Yes you are right. But I think that is how GC works. It is not always active. When memory is required, it runs and clears the memory of unreferenced variables. – gprathour Jun 15 '15 at 11:26
  • Yup. So, the problem he asks may not be evident by your example. Not even forcing GC after block ends may be visible. It is a though question :( – eduyayo Jun 15 '15 at 11:27
  • 1
    This answer isn't correct. Both the OP's original code and and their newly edited code makes the array eligible for garbage collection. The issue is that the GC is deliberately lazy to make it more efficient. – Philip Couling Jun 15 '15 at 11:29
1

You might want to read up on how the garbage collector works.

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

It's important to understand that the garbage collector is a bulk process. It does not clean up in a "timely fashion" when objects are no longer needed. An object may be eligible for garbage collection for a long time before it is actually cleaned up.

The garbage collector follows references for all static fields and all variables on the stack and everything referenced by those object etc. to mark every object it can find. It then frees everything which it did not mark.

This means that until it actively starts marking everything it can reference, it has no idea what can be cleaned up and what can't.

Since this marking process is very costly it is not performed very frequently and objects will hang round in memory for a significant time after they are needed.

Point of interest

There is a System.gc() method which can trigger the garbage collector. I would expect using this to free up unreferenced objects such as the array in your question.

You should not use this in your actual code it is very bad practise

Philip Couling
  • 13,581
  • 5
  • 53
  • 85