So I've found, with the MAT
that I keep creating multiple Threads
with every surfaceCreate
I think I need these threads, though, but this method causes multiple instances of ViewThread
, as a user navigates through my app, which is a memory leak.
How can I reorganize the way my threads are created and handled so that this doesn't happen, or how can I stop the leak from occurring?
@Override
public void surfaceCreated(SurfaceHolder holder) {
loading=false;
if (!mThread.isAlive()){
mThread = new ViewThread(this);
mThread.setMenuRunning(true);
mThread.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()){
mThread.setMenuRunning(false);
}
}
I opened and navigated away from the Career
Activity of my game five times, and this is what shows up on the MAT
EDIT: I've since found that depending on surfaceDestroyed
for the destruction of my threads is unreliable. I now call the appropriate thread-destroying calls from a different method, triggered onPause
.
You should use a WeakReference to reference the Career in your Thread. This way the reference will be cleared when there are no more hard references to the Career.
You can track all references in MAT by right clicking the career and choosing Path To GC Roots, then with all references. This will show you the path(s) to the object retained in memory. Make sure you either clear those references when you are done with the activity or make use of WeakReferences to have the GC clear them automatically.
Inside surfaceDestroyed
, you should wait to make sure that the thread stopped before you return.
You can refer to this question, for more details
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
mThread.setRunning(false);
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
So I fixed it by commenting one line:
@Override
public void surfaceCreated(SurfaceHolder holder) {
loading=false;
if (!mThread.isAlive()){
//mThread = new ViewThread(this);
mThread.setMenuRunning(true);
mThread.start();
}
}
This was also combined with the WeakReference
and the SurfaceDestroyed
answers.
I'll test it later and determine if it's just the removal of that one line, or a combination of that and the weak reference, or the other thing, then award the answer