異常出現頻率:非必現,乍看不可捉摸。
BUG導致:應用程序崩潰,過一小會兒會自動退出。
Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)
遇到這個問題很無奈,但是經過不斷探索終於找到了問題的原因!!!
這個問題非常不給面子,居然在給上級演示程序的時候突然崩壞! 哭哭哭!!!NND看老子一會兒怎么治你!!!
這個是典型的多線程引起的問題,
我當時的應用場景是:
SurfaceView里面有一個Bitmap成員變量
而我們都知道SurfaceView里面的繪圖方法是在一個新開的線程里面執行的,在這個繪圖方法里,會執行把Bitmap繪制到Canvas上面的操作
當我點擊一個按鈕的時候,可能會改變Bitmap的引用,指向另外一張處理完成的圖片,這個時候Bitmap這個成員變量會被我recycle(),釋放掉。
問題就在這里了,我在recycle這個Bitmap的時候,也許Thread中正在執行把Bitmap繪制到Canvas上的操作,可能剛好正在執行當中,或者執行了一半,而GC毫不留情地把這個Bitmap請上了天堂,就這樣,Java調用底層的API當中就突然發生了Error,因此這個問題才沒有任何的Java異常提示。
解決問題的辦法就是:
1. 在SurfaceView的按鈕點擊事件里用到Bitmap的地方改寫代碼:
Bitmap bmp = null; synchronized(mBmp) { bmp = mBmp; mBmp = filter(bmp); } // 釋放 if(bmp.isRecycled() == false) { bmp.recycle(); bmp = null; System.gc(); }
2. 在SurfaceView的Thread當中改寫代碼:
synchronized(mBmp) { // ... canvas.drawBitmap(mBmp, mMatrix, null); }
OK!