標籤:thread bsp oom 如何 異常 引用 其它 提高優先順序 演算法
1、anr異常面試問題講解
a) 什麼是anr?
應用程式無響應對話方塊
b) 造成anr的原因?
主線程中做了耗時操作
c) android中那些操作是在主線程呢?
activity的所有生命週期回調都是執行在主線程的
Service預設是執行在主線程的
BroadcastReceiver的onReceiver回調是執行在主線程的
沒有使用子線程的Looper的Handler的handlerMessage,post(Runnable)是執行在主線程的
AsyncTask的回調中除了doInBackground,其它都是執行在主線程
d) 如何解決anr
使用AsyncTask處理耗時IO操作
使用Thread或者HandlerThread提高優先順序
使用handler來處理背景工作執行緒的耗時任務
activity的onCreate和onResume回調中盡量避免耗時的代碼
2、oom異常面試問題講解
a) 什麼是oom ?
當前佔用的記憶體加上我們申請的記憶體資源超過了Dalvik虛擬機器的最大記憶體限制就會拋出的Out of memory異常
b) 一些容易混淆的概念
記憶體溢出 / 記憶體抖動 / 記憶體流失
記憶體溢出:就是oom
記憶體抖動:短時間內大量對象被建立然後馬上被釋放
記憶體流失:當程式不再使用到的記憶體時,釋放記憶體失敗而產生了無用的記憶體消耗
d) 如何解決oom
1.有關bitmap最佳化
圖片顯示(比如監聽listview滑動,停止的時候載入大圖)
及時釋放記憶體
bitmap的夠著方法都是私人的,通過BitmapFactory產生Bitmap到記憶體中都是通過jni實現的,簡單點說會有倆部分地區,一部分是java區,一部分是C區,但是Bitmap是通過java分配的,不用的時候也是由java的gc機制回收的。對應C地區不能及時回收的,所以這裡說的釋放記憶體就是釋放的c的那塊地區(通過
recycle方法,該方法內部調用了jni的方法)。要是不釋放只能等進程死了以後就會被釋放
圖片壓縮
inBitmap屬性(圖片複用)
捕獲異常
2.其它方法
listview:convertview / lru(三級緩衝)
避免在onDraw方法裡面執行對象的建立
謹慎使用多進程
3、 bitmap面試問題講解
a) recycle :釋放bitmap記憶體的時候會釋放所對應的native的記憶體,但是不會立即釋放,但是調用完就不能使用該bitmap了,是無法復原的。官方不建議主動調用。記憶體回收行程主動會清理。
b) LRU:三級緩衝,內部是通過map實現的,裡面提供了put、get方法來完成緩衝的添加和擷取操作。當緩衝滿的時候,lru演算法會提供trimToSize刪除最久或者使用最少的緩衝對象,添加新的緩衝對象
c) 計算inSampleSize:
d) 縮圖
/** * 擷取縮圖 * @param imagePath:檔案路徑 * @param width:縮圖寬度 * @param height:縮圖高度 * @return */ public static Bitmap getImageThumbnail(String imagePath, int width, int height) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //關於inJustDecodeBounds的作用將在下文敘述 Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options); int h = options.outHeight;//擷取圖片高度 int w = options.outWidth;//擷取圖片寬度 int scaleWidth = w / width; //計算寬度縮放比 int scaleHeight = h / height; //計算高度縮放比 int scale = 1;//初始縮放比 if (scaleWidth < scaleHeight) {//選擇合適的縮放比 scale = scaleWidth; } else { scale = scaleHeight; } if (scale <= 0) {//判斷縮放比是否符合條件 be = 1; } options.inSampleSize = scale; // 重新讀入圖片,讀取縮放後的bitmap,注意這次要把inJustDecodeBounds 設為 false options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(imagePath, options); // 利用ThumbnailUtils來建立縮圖,這裡要指定要縮放哪個Bitmap對象 bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,ThumbnailUtils.OPTIONS_RECYCLE_INPUT); return bitmap; }
e) 三級緩衝
網路、本地、記憶體三級緩衝,減少流量的使用
4、 ui卡頓面試問題講解
a) UI卡頓的原理
60fps -> 16ms
overdraw過度繪製
b) UI卡頓的原因分析
1.人為在UI線程中做輕微耗時操作,導致UI線程卡頓
2.布局Layout過於複雜,無法在16ms內完成渲染
3.同一時間動畫執行的次數過多,導致CPU、GPU的負載過重
4.View的過度繪製,導致某些像素在同一幀內被繪製多次,從而使CPU、GPU的負載過重
5.View頻繁的觸發measure、layout,導致measure、layout累計耗時過多及整個View頻繁的重新渲染
6.記憶體頻繁觸發gc過多,導致暫時阻塞渲染操作
7.冗餘資源及邏輯等導致載入和執行的緩慢
8.ANR
c) UI卡頓總結
1.布局最佳化
2.列表及adapter最佳化
3.背景和圖片等記憶體配置最佳化
4.避免ANR
4、 記憶體流失
a) java記憶體流失基礎知識
1. java記憶體的分配策略
靜態儲存區(方法區):主要存放待用資料、全域 static 資料和常量。這塊記憶體在程式編譯時間就已經分配好,並且在程式整個運行期間都存在。
棧區:當方法被執行時,方法體內的局部變數(其中包括基礎資料類型、對象的引用)都在棧上建立,並在方法執行結束時這些局部變數所持有的記憶體將會自動被釋放。因為棧記憶體配置運算內建於處理器的指令集中,效率很高,但是分配的記憶體容量有限。
堆區 : 又稱動態記憶體分配,通常就是指在程式運行時直接 new 出來的記憶體,也就是對象的執行個體。這部分記憶體在不使用時將會由 Java 記憶體回收行程來負責回收。
2. java是如何管理記憶體的
3. java中的記憶體流失
記憶體流失是指無用對象(不再使用的對象)持續佔有記憶體或無用對象的記憶體得不到及時釋放,從而造成的記憶體空間的浪費稱為記憶體流失
b) android記憶體流失
第8章 Android異常與效能最佳化相關面試問題