1. 程式人生 > >android系統優化(18)--系統性能優化第5季

android系統優化(18)--系統性能優化第5季

1)Threading Performance

在程式開發的實踐當中,為了讓程式表現得更加流暢,我們肯定會需要使用到多執行緒來提升程式的併發執行效能。但是編寫多執行緒併發的程式碼一直以來都是一個相對棘手的問題,所以想要獲得更佳的程式效能,我們非常有必要掌握多執行緒併發程式設計的基礎技能。

眾所周知,Android程式的大多數程式碼操作都必須執行在主執行緒,例如系統事件(例如裝置螢幕發生旋轉),輸入事件(例如使用者點選滑動等),程式回撥服務,UI繪製以及鬧鐘事件等等。那麼我們在上述事件或者方法中插入的程式碼也將執行在主執行緒。

android_perf_5_threading_main_thread

一旦我們在主執行緒裡面添加了操作複雜的程式碼,這些程式碼就很可能阻礙主執行緒去響應點選/滑動事件,阻礙主執行緒的UI繪製等等。我們知道,為了讓螢幕的重新整理幀率達到60fps,我們需要確保16ms內完成單次重新整理的操作。一旦我們在主執行緒裡面執行的任務過於繁重就可能導致接收到重新整理訊號的時候因為資源被佔用而無法完成這次重新整理操作,這樣就會產生掉幀的現象,重新整理幀率自然也就跟著下降了(一旦重新整理幀率降到20fps左右,使用者就可以明顯感知到卡頓不流暢了)。

android_perf_5_threading_dropframe

為了避免上面提到的掉幀問題,我們需要使用多執行緒的技術方案,把那些操作複雜的任務移動到其他執行緒當中執行,這樣就不容易阻塞主執行緒的操作,也就減小了出現掉幀的可能性。

android_perf_5_threading_workthread

那麼問題來了,為主執行緒減輕負的多執行緒方案有哪些呢?這些方案分別適合在什麼場景下使用?Android系統為我們提供了若干組工具類來幫助解決這個問題。

  • AsyncTask: 為UI執行緒與工作執行緒之間進行快速的切換提供一種簡單便捷的機制。適用於當下立即需要啟動,但是非同步執行的生命週期短暫的使用場景。
  • HandlerThread: 為某些回撥方法或者等待某些任務的執行設定一個專屬的執行緒,並提供執行緒任務的排程機制。
  • ThreadPool
    : 把任務分解成不同的單元,分發到各個不同的執行緒上,進行同時併發處理。
  • IntentService: 適合於執行由UI觸發的後臺Service任務,並可以把後臺任務執行的情況通過一定的機制反饋給UI。

瞭解這些系統提供的多執行緒工具類分別適合在什麼場景下,可以幫助我們選擇合適的解決方案,避免出現不可預期的麻煩。雖然使用多執行緒可以提高程式的併發量,但是我們需要特別注意因為引入多執行緒而可能伴隨而來的記憶體問題。舉個例子,在Activity內部定義的一個AsyncTask,它屬於一個內部類,該類本身和外面的Activity是有引用關係的,如果Activity要銷燬的時候,AsyncTask還仍然在執行,這會導致Activity沒有辦法完全釋放,從而引發記憶體洩漏。所以說,多執行緒是提升程式效能的有效手段之一,但是使用多執行緒卻需要十分謹慎小心,如果不瞭解背後的執行機制以及使用的注意事項,很可能引起嚴重的問題。

2)Understanding Android Threading

通常來說,一個執行緒需要經歷三個生命階段:開始,執行,結束。執行緒會在任務執行完畢之後結束,那麼為了確保執行緒的存活,我們會在執行階段給執行緒賦予不同的任務,然後在裡面新增退出的條件從而確保任務能夠執行完畢後退出。

android_perf_5_thread_lifecycle

在很多時候,執行緒不僅僅是線性執行一系列的任務就結束那麼簡單的,我們會需要增加一個任務佇列,讓執行緒不斷的從任務佇列中獲取任務去進行執行,另外我們還可能線上程執行的任務過程中與其他的執行緒進行協作。如果這些細節都交給我們自己來處理,這將會是件極其繁瑣又容易出錯的事情。

android_perf_5_thread_thread

所幸的是,Android系統為我們提供了Looper,Handler,MessageQueue來幫助實現上面的執行緒任務模型:

Looper: 能夠確保執行緒持續存活並且可以不斷的從任務佇列中獲取任務並進行執行。

android_perf_5_thread_looper

Handler: 能夠幫助實現佇列任務的管理,不僅僅能夠把任務插入到佇列的頭部,尾部,還可以按照一定的時間延遲來確保任務從佇列中能夠來得及被取消掉。

android_perf_5_thread_handler

MessageQueue: 使用Intent,Message,Runnable作為任務的載體在不同的執行緒之間進行傳遞。

android_perf_5_thread_messagequeue

把上面三個元件打包到一起進行協作,這就是HandlerThread

android_perf_5_thread_handlerthread

我們知道,當程式被啟動,系統會幫忙建立程序以及相應的主執行緒,而這個主執行緒其實就是一個HandlerThread。這個主執行緒會需要處理系統事件,輸入事件,系統回撥的任務,UI繪製等等任務,為了避免主執行緒任務過重,我們就會需要不斷的開啟新的工作執行緒來處理那些子任務。

3)Memory & Threading

增加併發的執行緒數會導致記憶體消耗的增加,平衡好這兩者的關係是非常重要的。我們知道,多執行緒併發訪問同一塊記憶體區域有可能帶來很多問題,例如讀寫的許可權爭奪問題,ABA問題等等。為了解決這些問題,我們會需要引入的概念。

在Android系統中也無法避免因為多執行緒的引入而導致出現諸如上文提到的種種問題。Android UI物件的建立,更新,銷燬等等操作都預設是執行在主執行緒,但是如果我們在非主執行緒對UI物件進行操作,程式將可能出現異常甚至是崩潰。

android_perf_5_memory_thread_update

另外,在非UI執行緒中直接持有UI物件的引用也很可能出現問題。例如Work執行緒中持有某個UI物件的引用,在Work執行緒執行完畢之前,UI物件在主執行緒中被從ViewHierarchy中移除了,這個時候UI物件的任何屬性都已經不再可用了,另外對這個UI物件的更新操作也都沒有任何意義了,因為它已經從ViewHierarchy中被移除,不再繪製到畫面上了。

android_perf_5_memory_view_remove

不僅如此,View物件本身對所屬的Activity是有引用關係的,如果工作執行緒持續保有View的引用,這就可能導致Activity無法完全釋放。除了直接顯式的引用關係可能導致記憶體洩露之外,我們還需要特別留意隱式的引用關係也可能導致洩露。例如通常我們會看到在Activity裡面定義的一個AsyncTask,這種型別的AsyncTask與外部的Activity是存在隱式引用關係的,只要Task沒有結束,引用關係就會一直存在,這很容易導致Activity的洩漏。更糟糕的情況是,它不僅僅發生了記憶體洩漏,還可能導致程式異常或者崩潰。

android_perf_5_memory_asynctask

為了解決上面的問題,我們需要謹記的原則就是:不要在任何非UI執行緒裡面去持有UI物件的引用。系統為了確保所有的UI物件都只會被UI執行緒所進行建立,更新,銷燬的操作,特地設計了對應的工作機制(當Activity被銷燬的時候,由該Activity所觸發的非UI執行緒都將無法對UI物件進行操作,否者就會丟擲程式執行異常的錯誤)來防止UI物件被錯誤的使用。

4)Good AsyncTask Hunting

AsyncTask是一個讓人既愛又恨的元件,它提供了一種簡便的非同步處理機制,但是它又同時引入了一些令人厭惡的麻煩。一旦對AsyncTask使用不當,很可能對程式的效能帶來負面影響,同時還可能導致記憶體洩露。

舉個例子,常遇到的一個典型的使用場景:使用者切換到某個介面,觸發了介面上的圖片的載入操作,因為圖片的載入相對來說耗時比較長,我們需要在子執行緒中處理圖片的載入,當圖片在子執行緒中處理完成之後,再把處理好的圖片返回給主執行緒,交給UI更新到畫面上。

android_perf_5_asynctask_main

AsyncTask的出現就是為了快速的實現上面的使用場景,AsyncTask把在主執行緒裡面的準備工作放到onPreExecute()方法裡面進行執行,doInBackground()方法執行在工作執行緒中,用來處理那些繁重的任務,一旦任務執行完畢,就會呼叫onPostExecute()方法返回到主執行緒。

android_perf_5_asynctask_mode

使用AsyncTask需要注意的問題有哪些呢?請關注以下幾點:

  • 首先,預設情況下,所有的AsyncTask任務都是被線性排程執行的,他們處在同一個任務隊列當中,按順序逐個執行。假設你按照順序啟動20個AsyncTask,一旦其中的某個AsyncTask執行時間過長,佇列中的其他剩餘AsyncTask都處於阻塞狀態,必須等到該任務執行完畢之後才能夠有機會執行下一個任務。情況如下圖所示:

android_perf_5_asynctask_single_queue

為了解決上面提到的線性佇列等待的問題,我們可以使用AsyncTask.executeOnExecutor()強制指定AsyncTask使用執行緒池併發排程任務。

android_perf_5_asynctask_thread_pool

  • 其次,如何才能夠真正的取消一個AsyncTask的執行呢?我們知道AsyncTaks有提供cancel()的方法,但是這個方法實際上做了什麼事情呢?執行緒本身並不具備中止正在執行的程式碼的能力,為了能夠讓一個執行緒更早的被銷燬,我們需要在doInBackground()的程式碼中不斷的新增程式是否被中止的判斷邏輯,如下圖所示:

android_perf_5_asynctask_cancel

一旦任務被成功中止,AsyncTask就不會繼續呼叫onPostExecute(),而是通過呼叫onCancelled()的回撥方法反饋任務執行取消的結果。我們可以根據任務回撥到哪個方法(是onPostExecute還是onCancelled)來決定是對UI進行正常的更新還是把對應的任務所佔用的記憶體進行銷燬等。

  • 最後,使用AsyncTask很容易導致記憶體洩漏,一旦把AsyncTask寫成Activity的內部類的形式就很容易因為AsyncTask生命週期的不確定而導致Activity發生洩漏。

android_perf_5_memory_asynctask

綜上所述,AsyncTask雖然提供了一種簡單便捷的非同步機制,但是我們還是很有必要特別關注到他的缺點,避免出現因為使用錯誤而導致的嚴重系統性能問題。

5)Getting a HandlerThread

大多數情況下,AsyncTask都能夠滿足多執行緒併發的場景需要(在工作執行緒執行任務並返回結果到主執行緒),但是它並不是萬能的。例如開啟相機之後的預覽幀資料是通過onPreviewFrame()的方法進行回撥的,onPreviewFrame()open()相機的方法是執行在同一個執行緒的。

android_perf_5_handlerthread_camera_open

如果這個回撥方法執行在UI執行緒,那麼在onPreviewFrame()裡面將要執行的資料轉換操作將和主執行緒的介面繪製,事件傳遞等操作爭搶系統資源,這就有可能影響到主介面的表現效能。

android_perf_5_handlerthread_main_thread2

我們需要確保onPreviewFrame()執行在工作執行緒。如果使用AsyncTask,會因為AsyncTask預設的線性執行的特性(即使換成併發執行)會導致因為無法把任務及時傳遞給工作執行緒而導致任務在主執行緒中被延遲,直到工作執行緒空閒,才可以把任務切換到工作執行緒中進行執行。

android_perf_5_handlerthread_asynctask

所以我們需要的是一個執行在工作執行緒,同時又能夠處理佇列中的複雜任務的功能,而HandlerThread的出現就是為了實現這個功能的,它組合了Handler,MessageQueue,Looper實現了一個長時間執行的執行緒,不斷的從佇列中獲取任務進行執行的功能。

android_perf_5_handlerthread_outline

回到剛才的處理相機回撥資料的例子,使用HandlerThread我們可以把open()操作與onPreviewFrame()的操作執行在同一個執行緒,同時還避免了AsyncTask的弊端。如果需要在onPreviewFrame()裡面更新UI,只需要呼叫runOnUiThread()方法把任務回撥給主執行緒就夠了。

android_perf_5_handlerthread_camera

HandlerThread比較合適處理那些在工作執行緒執行,需要花費時間偏長的任務。我們只需要把任務傳送給HandlerThread,然後就只需要等待任務執行結束的時候通知返回到主執行緒就好了。

另外很重要的一點是,一旦我們使用了HandlerThread,需要特別注意給HandlerThread設定不同的執行緒優先順序,CPU會根據設定的不同執行緒優先順序對所有的執行緒進行排程優化。

android_perf_5_handlerthread_priority

掌握HandlerThread與AsyncTask之間的優缺點,可以幫助我們選擇合適的方案。

6)Swimming in Threadpools

執行緒池適合用在把任務進行分解,併發進行執行的場景。通常來說,系統裡面會針對不同的任務設定一個單獨的守護執行緒用來專門處理這項任務。例如使用Networking Thread用來專門處理網路請求的操作,使用IO Thread用來專門處理系統的I\O操作。針對那些場景,這樣設計是沒有問題的,因為對應的任務單次執行的時間並不長而且可以是順序執行的。但是這種專屬的單執行緒並不能滿足所有的情況,例如我們需要一次性decode 40張圖片,每個執行緒需要執行4ms的時間,如果我們使用專屬單執行緒的方案,所有圖片執行完畢會需要花費160ms(40*4),但是如果我們建立10個執行緒,每個執行緒執行4個任務,那麼我們就只需要16ms就能夠把所有的圖片處理完畢。

android_perf_5_threadpool_1

為了能夠實現上面的執行緒池模型,系統為我們提供了ThreadPoolExecutor幫助類來簡化實現,剩下需要做的就只是對任務進行分解就好了。

android_perf_5_threadpool_2

使用執行緒池需要特別注意同時併發執行緒數量的控制,理論上來說,我們可以設定任意你想要的併發數量,但是這樣做非常的不好。因為CPU只能同時執行固定數量的執行緒數,一旦同時併發的執行緒數量超過CPU能夠同時執行的閾值,CPU就需要花費精力來判斷到底哪些執行緒的優先順序比較高,需要在不同的執行緒之間進行排程切換。

android_perf_5_threadpool_3

一旦同時併發的執行緒數量達到一定的量級,這個時候CPU在不同執行緒之間進行排程的時間就可能過長,反而導致效能嚴重下降。另外需要關注的一點是,每開一個新的執行緒,都會耗費至少64K+的記憶體。為了能夠方便的對執行緒數量進行控制,ThreadPoolExecutor為我們提供了初始化的併發執行緒數量,以及最大的併發數量進行設定。

android_perf_5_threadpool_4

另外需要關注的一個問題是:Runtime.getRuntime().availableProcesser()方法並不可靠,他返回的值並不是真實的CPU核心數,因為CPU會在某些情況下選擇對部分核心進行睡眠處理,在這種情況下,返回的數量就只能是啟用的CPU核心數。

7)The Zen of IntentService

預設的Service是執行在主執行緒的,可是通常情況下,這很容易影響到程式的繪製效能(搶佔了主執行緒的資源)。除了前面介紹過的AsyncTask與HandlerThread,我們還可以選擇使用IntentService來實現非同步操作。IntentService繼承自普通Service同時又在內部建立了一個HandlerThread,在onHandlerIntent()的回撥裡面處理扔到IntentService的任務。所以IntentService就不僅僅具備了非同步執行緒的特性,還同時保留了Service不受主頁面生命週期影響的特點。

android_perf_5_intentservice_outline

如此一來,我們可以在IntentService裡面通過設定鬧鐘間隔性的觸發非同步任務,例如重新整理資料,更新快取的圖片或者是分析使用者操作行為等等,當然處理這些任務需要小心謹慎。

使用IntentService需要特別留意以下幾點:

  • 首先,因為IntentService內建的是HandlerThread作為非同步執行緒,所以每一個交給IntentService的任務都將以佇列的方式逐個被執行到,一旦佇列中有某個任務執行時間過長,那麼就會導致後續的任務都會被延遲處理。
  • 其次,通常使用到IntentService的時候,我們會結合使用BroadcastReceiver把工作執行緒的任務執行結果返回給主UI執行緒。使用廣播容易引起效能問題,我們可以使用LocalBroadcastManager來發送只在程式內部傳遞的廣播,從而提升廣播的效能。我們也可以使用runOnUiThread()快速回調到主UI執行緒。
  • 最後,包含正在執行的IntentService的程式相比起純粹的後臺程式更不容易被系統殺死,該程式的優先順序是介於前臺程式與純後臺程式之間的。

8)Threading and Loaders

當啟動工作執行緒的Activity被銷燬的時候,我們應該做點什麼呢?為了方便的控制工作執行緒的啟動與結束,Android為我們引入了Loader來解決這個問題。我們知道Activity有可能因為使用者的主動切換而頻繁的被建立與銷燬,也有可能是因為類似螢幕發生旋轉等被動原因而銷燬再重建。在Activity不停的建立與銷燬的過程當中,很有可能因為工作執行緒持有Activity的View而導致記憶體洩漏(因為工作執行緒很可能持有View的強引用,另外工作執行緒的生命週期還無法保證和Activity的生命週期一致,這樣就容易發生記憶體洩漏了)。除了可能引起記憶體洩漏之外,在Activity被銷燬之後,工作執行緒還繼續更新檢視是沒有意義的,因為此時檢視已經不在介面上顯示了。

android_perf_5_loader_bad

Loader的出現就是為了確保工作執行緒能夠和Activity的生命週期保持一致,同時避免出現前面提到的問題。

android_perf_5_loader_good

LoaderManager會對查詢的操作進行快取,只要對應Cursor上的資料來源沒有發生變化,在配置資訊發生改變的時候(例如螢幕的旋轉),Loader可以直接把快取的資料回撥到onLoadFinished(),從而避免重新查詢資料。另外系統會在Loader不再需要使用到的時候(例如使用Back按鈕退出當前頁面)回撥onLoaderReset()方法,我們可以在這裡做資料的清除等等操作。

在Activity或者Fragment中使用Loader可以方便的實現非同步載入的框架,Loader有諸多優點。但是實現Loader的這套程式碼還是稍微有點點複雜,Android官方為我們提供了使用Loader的示例程式碼進行參考學習。

9)The Importance of Thread Priority

理論上來說,我們的程式可以創建出非常多的子執行緒一起併發執行的,可是基於CPU時間片輪轉排程的機制,不可能所有的執行緒都可以同時被排程執行,CPU需要根據執行緒的優先順序賦予不同的時間片。

android_perf_5_threadpriority_CPU

Android系統會根據當前執行的可見的程式和不可見的後臺程式對執行緒進行歸類,劃分為forground的那部分執行緒會大致佔用掉CPU的90%左右的時間片,background的那部分執行緒就總共只能分享到5%-10%左右的時間片。之所以設計成這樣是因為forground的程式本身的優先順序就更高,理應得到更多的執行時間。

android_perf_5_threadpriority_90

預設情況下,新建立的執行緒的優先順序預設和建立它的母執行緒保持一致。如果主UI執行緒創建出了幾十個工作執行緒,這些工作執行緒的優先順序就預設和主執行緒保持一致了,為了不讓新建立的工作執行緒和主執行緒搶佔CPU資源,需要把這些執行緒的優先順序進行降低處理,這樣才能給幫組CPU識別主次,提高主執行緒所能得到的系統資源。

android_perf_5_threadpriority_less

在Android系統裡面,我們可以通過android.os.Process.setThreadPriority(int)設定執行緒的優先順序,引數範圍從-20到24,數值越小優先順序越高。Android系統還為我們提供了以下的一些預設值,我們可以通過給不同的工作執行緒設定不同數值的優先順序來達到更細粒度的控制。

android_perf_5_threadpriority_const

大多數情況下,新建立的執行緒優先順序會被設定為預設的0,主執行緒設定為0的時候,新建立的執行緒還可以利用THREAD_PRIORITY_LESS_FAVORABLE或者THREAD_PRIORITY_MORE_FAVORABLE來控制執行緒的優先順序。

android_perf_5_threadpriority_value

Android系統裡面的AsyncTask與IntentService已經預設幫助我們設定執行緒的優先順序,但是對於那些非官方提供的多執行緒工具類,我們需要特別留意根據需要自己手動來設定執行緒的優先順序。

android_perf_5_threadpriority_asynctask android_perf_5_threadpriority_intentservice

10)Profile GPU Rendering : M Update

從Android M系統開始,系統更新了GPU Profiling的工具來幫助我們定位UI的渲染效能問題。早期的CPU Profiling工具只能粗略的顯示出Process,Execute,Update三大步驟的時間耗費情況。

android_perf_5_gpu_profiling_old

相關推薦

android系統優化18--系統性優化5

1)Threading Performance在程式開發的實踐當中,為了讓程式表現得更加流暢,我們肯定會需要使用到多執行緒來提升程式的併發執行效能。但是編寫多執行緒併發的程式碼一直以來都是一個相對棘手的問題,所以想要獲得更佳的程式效能,我們非常有必要掌握多執行緒併發程式設計的

Android 系統性優化11---UC效能優化方案

       一、效能優化六項指標:              效能、記憶體、穩定性、流量、電量、安裝包大小;       二、背景 ---- Android程式卡頓產生原因:              1、Android系統低效              --渲染執行緒、同步介面、廣播機制         

Android系統架構

查詢 核心 手機 例如 ava 模塊 api 操作系統 運行   一、Android系統版本簡介   Android操作系統已占據了手機操作系統的大半壁江山,截至本文寫作時,Android操作系統系統版本及其詳細信息,已發生了變化,具體信息見下表,當然也可以訪問https:

架構設計:系統儲存18——Redis叢集方案:高效能

1、概述 通過上一篇文章(《架構設計:系統儲存(17)——Redis叢集方案:高可用》)的內容,Redis主從複製的基本功能和進行Redis高可用叢集監控的Sentinel基本功能基本呈現給了讀者。雖然本人並不清楚上一篇根據筆者實際工作經驗所撰寫的文章有什麼重

Android 效能優化之佈局優化

60fps VS 16ms 根據Google官方出品的Android效能優化典範,60幀每秒是目前最合適的影象顯示速度,事實上絕大多數的Android裝置也是按照每秒60幀來重新整理的。為了讓螢幕的重新整理幀率達到60fps,我們需要確保在時間16ms(100

Android效能優化記憶體洩露優化靜態變數、單例模式、屬性動畫

記憶體洩露優化分為兩個方面,一方面是在開發過程中避免寫出有記憶體洩露的程式碼,另一方面是通過一些分析工具比如 MAT來找出潛在的記憶體洩露繼而解決。 一、靜態變數導致記憶體洩露。一般情況下靜態變數引用

Android 4 學習18:搜尋

參考《Professional Android 4 Development》 搜尋 通過下面這幾種方式可以給應用程式新增搜尋功能: Search Bar Search View Quick Search Box 可搜尋的Content Provider 首

Service與Android系統設計4-- ServiceManager

System Service的驅動形式 --- ServiceManager 對於ServiceManager的使用,我們在應用程式程式設計時也會經常使用到,比如我們需要使用Sensor時,我們一般會做如下的呼叫: mSensorManager = (SensorMan

android 系統服務service

-服務(service)是Android 系統中的重要元件,服務可以在不顯示介面的情況下在後臺執行制定的任務或者進行兩個不同程序間的通訊, android在後臺執行著許多服務,這些服務在系統啟動時被開啟,支援系統的正常工作。例如:來電顯示服務,在程式設計是通過

Service與Android系統設計6--- Native Service

Native Service Native Service,這是Android系統裡的一種特色,就是通過C++或是C程式碼寫出來的,供Java進行遠端呼叫的Remote Service,因為C/C++程式碼生成的是Native程式碼(機器程式碼),於是叫Native Se

Analysis ServicesSSAS優化

顯示 onf 線程池 並發 https srv 技術分享 conf http 1、聚合選項中添加聚合,以空間換時間提升性能。 如下圖: 性能提升百分比越高,聚合數越高,生成的Cube越大,這就是以空間換時間。 2、修改SSAS服務器上的線程池配置選項、提升

數據庫優化—— MySQL索引優化

大表加索引 運算 維護 重構 unit num .sh 規範 -s 目錄 MySQL的索引優化 一、MySQL 5.7的初始化配置 二、MySQL配置文件 1、配置 2、配置文件作用 三、多實例 1、創建相關的目錄 2、創建實例的配置文件 3、初始化 4、授權 5、啟動

Android JNI程式設計——使用AndroidStudio編寫一個JNI程式

1.簡單介紹一下NDK和JNI NDK:NDK是Native Development Kit的縮寫,是Google提供的一套工具集,可以讓你其他語言(C、C++或彙編)開發 Android的 JNI。NDK可以編譯多平臺的so,開發人員只需要簡單修改 mk

MYSQL優化:查詢優化

關於mysql查詢過程可參考上篇文章語法解析和預處理MySQL通過關鍵字將SQL語句進行解析,並生成一顆對應的解析樹。這個過程解析器主要通過語法規則來驗證和解析。比如SQL中是否使用了錯誤的關鍵字或者關鍵字的順序是否正確等等。預處理則會根據MySQL規則進一步檢查解析樹是否合

java基礎學習6瘋狂java講義5章課後習題解答原始碼

1 class Students{ // define member variable private int age; private String name,gende

android系統性優化63---Android APP 卡頓問題分析及解決方案

使用者對卡頓的感知, 主要來源於介面的重新整理. 而介面的效能主要是依賴於裝置的UI渲染效能. 如果我們的UI設計過於複雜, 或是實現不夠友好,計算繪製演算法不夠優化, 裝置又不給力, 介面就會像卡住了一樣, 給使用者卡頓的感覺.如果你的應用介面出現卡頓不流暢的情況,不用懷疑,這很大原因是你沒有在16ms完成

Android 系統性優化36---顯示效能指標

    從 Android 誕生的那一刻起,流暢度就為眾人所關注。一時之間,似乎所有人都在討論 Android 和 iOS 誰的流暢度更好。但是,毫不誇張的說,流暢度絕對是 Android 眾多效能維度中最為奇葩的一個。因為,為了刻畫這一效能維度,業界設計了各式各樣的指標來對

Android 系統性優化16--Android 系統性優化4

1)Cachematters for networking想要使得Android系統上的網路訪問操作更加的高效就必須做好網路資料的快取。這是提高網路訪問效能最基礎的步驟之一。從手機的快取中直接讀取資料肯定比從網路上獲取資料要更加的便捷高效,特別是對於那些會被頻繁訪問到的資料,

Android 系統性優化52---移動端效能監控方案Hertz

效能問題是造成App使用者流失的罪魁禍首之一。App的效能問題包括崩潰、網路請求錯誤或超時、響應速度慢、列表滾動卡頓、流量大、耗電等等。而導致App效能低下的原因有很多,除去裝置硬體和軟體的外部因素,其中大部分是開發者錯誤地使用執行緒、鎖、系統函式、程式設計正規化、資料結構等導致的。即便是最有經驗的程式設計師

Android 系統性優化34---Android UI 效能優化

Android官網 Slow rendering;個人覺得非常有價值,比如指出 物件分配、垃圾回收(GC)、執行緒排程以及Binder呼叫 是Android系統中常見的卡頓原因,更重要的是給出了定位和解決這些問題的方案;而非簡單地告訴你避免物件分配,減少佈局層級,減少過度