1

My Problem

I have a timer which is initalized like so and calls a method to update an object. The problem is I am getting GC_CONCURRENT outputs in my LogCat every time the timer is fired.

11-01 11:56:43.042: D/dalvikvm(30950): GC_CONCURRENT freed 774K, 52% free 3303K/6791K, external 1763K/2129K, paused 3ms+4ms

Here is my timer initialisation along with the task.

    if (CCTrackManager.timer == null) 
        CCTrackManager.timer = new Timer("TrackUpdate");
    MyTimerTask task = new MyTimerTask();
    CCTrackManager.timer.scheduleAtFixedRate(task, 0, 1000);

So this is called once and not called again, (unless the timer is stopped and restarted).

My update method looks as so.

 public void addSecondToTrackDuration() {
      this._currentRecordingTrack.setDuration(this._currentRecordingTrack.getDuration() + 1);
      this.mListener.trackUpdated(this._currentRecordingTrack);
  }

Then here is my Handler which I use to handle getting the value from this thread into my UI thread.

//----------------------------------------------------------------------
    // HANDLES THE UPDATE OF THE TRACK. NEEDS HANDLER BECAUSE THE TIMER WHICH CALLS THIS RUNS ON ANOTHER THREAD 
    //----------------------------------------------------------------------
    static class UpdateTrackHandler extends Handler {

        WeakReference<MainActivity> mActivity;
        UpdateTrackHandler(MainActivity act) {
            mActivity = new WeakReference<MainActivity>(act);
        }

        @Override 
        public void handleMessage(Message msg) {
            TrackFragment tf = (TrackFragment) mActivity.get().getSupportFragmentManager().findFragmentByTag(RECORDING_TRACK_FRAG);
            if (tf != null) {
                tf.updateViewWithTrack((CCTrack)msg.obj);
            }
        }
    }

    UpdateTrackHandler mHandler = new UpdateTrackHandler(this);

    //----------------------------------------------------------------------
        // CALLED FROM CCTRACKMANAGER WHEN AN UPDATE OCCURS ON THE  CURRENT RECORDING TRACK
        //---------------------------------------------------------------------- 
        public void trackUpdated(CCTrack track) {
            Message msg = new Message();
            msg.obj = track;
            mHandler.sendMessage(msg);
        }

I don't think this is the problem. I think the problem is in the fragment where I am actually updating the TextView as when I comment it out this.durationValueTxtView.setText("TIME");, it doesn't happen anymore.

public void updateViewWithTrack(CCTrack track) {
    this.durationValueTxtView.setText("TIME");
}

My Question

Am I missing something in terms of my handler creation, timer creation, timer task creation, textview reference? Anything?

Thanks in advance

StuStirling
  • 15,601
  • 23
  • 93
  • 150
  • Something seems weird here. A simple TextView update with "TIME" shouldn't be 700k. Are you using a lot of strings? – Joe Plante Nov 09 '12 at 20:11
  • Do you mean throughout my application? If so then I guess I do. Should I declare every String as resource and reference them that way? (The ones that are static anyway) – StuStirling Nov 10 '12 at 11:51
  • It's good practice to declare them in R. However, you get a lot of GC calls if you do a lot of String processing without using StringBuilder. Honestly not sure if this could be it – Joe Plante Nov 12 '12 at 13:23
  • GC_CONCURRENT itself is not an error, but may point to a memory leak or poor memory management. From the little code you posted is very hard to really tell if or which might be the case here. – stoilkov Nov 13 '12 at 11:02

2 Answers2

1

Why are you sending CCTrack instance in updateViewWithTrack(CCTrack track) when you aren't using it ? Try removing it, your code might work fine.

  • GC_CONCURRENT is thrown whenever is a memory leak in your code.
  • Try reading this and this
Gaurav Arora
  • 17,124
  • 5
  • 33
  • 44
  • I am using it normally as I am using the CCTrack object to set the text of the text view – StuStirling Nov 08 '12 at 11:08
  • Don't worry, it isn't a big issue. Unless your memory goes really low. Anyways, you could remove this message temporarily by increasing the HeapSize using `dalvik.system.VMRuntime.getRuntime().setMinimumHeapSize(32 * 1024 * 1024)` However this approach is not recommended. – Gaurav Arora Nov 08 '12 at 11:32
0

It seams that you simply try to update UI from outside of UI thread - i.e. from TimerTask You must only post message to handler and update UI from handler code. Take a look here: Android timer? How-to?

Community
  • 1
  • 1
piotrpo
  • 12,398
  • 7
  • 42
  • 58