<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                > 原文出處:http://hukai.me/android-performance-memory/ > 作者: 胡凱 Google近期在Udacity上發布了[Android性能優化的在線課程](https://www.udacity.com/course/ud825),分別從渲染,運算與內存,電量幾個方面介紹了如何去優化性能,這些課程是Google之前在Youtube上發布的[Android性能優化典范](http://hukai.me/android-performance-patterns/)專題課程的細化與補充。 下面是內存篇章的學習筆記,部分內容與前面的性能優化典范有重合,歡迎大家一起學習交流! ## 1)Memory, GC, and Performance 眾所周知,與C/C++需要通過手動編碼來申請以及釋放內存有所不同,Java擁有GC的機制。Android系統里面有一個**Generational Heap Memory**的模型,系統會根據內存中不同的內存數據類型分別執行不同的GC操作。例如,最近剛分配的對象會放在Young Generation區域,這個區域的對象通常都是會快速被創建并且很快被銷毀回收的,同時這個區域的GC操作速度也是比Old Generation區域的GC操作速度更快的。 ![](https://box.kancloud.cn/2015-08-21_55d6c57183b4b.png) 除了速度差異之外,執行GC操作的時候,所有線程的任何操作都會需要暫停,等待GC操作完成之后,其他操作才能夠繼續運行。 ![](https://box.kancloud.cn/2015-08-21_55d6c58009fb7.png) 通常來說,單個的GC并不會占用太多時間,但是大量不停的GC操作則會顯著占用幀間隔時間(16ms)。如果在幀間隔時間里面做了過多的GC操作,那么自然其他類似計算,渲染等操作的可用時間就變得少了。 ## 2)Memory Monitor Walkthrough Android Studio中的Memory Monitor可以很好的幫助我們查看程序的內存使用情況。 ![](https://box.kancloud.cn/2015-08-21_55d6c58718124.png) ![](https://box.kancloud.cn/2015-08-21_55d6c58a90b72.png) ![](https://box.kancloud.cn/2015-08-21_55d6c58e596c2.png) ## 3)Memory Leaks 內存泄漏表示的是不再用到的對象因為被錯誤引用而無法進行回收。 ![](https://box.kancloud.cn/2015-08-21_55d6c59177938.png) 發生內存泄漏會導致Memory Generation中的剩余可用Heap Size越來越小,這樣會導致頻繁觸發GC,更進一步引起性能問題。 舉例內存泄漏,下面`init()`方法來自某個自定義View: ~~~ private void init() { ListenerCollector collector = new ListenerCollector(); collector.setListener(this, mListener); } ~~~ 上面的例子容易存在內存泄漏,如果activity因為設備翻轉而重新創建,自定義的View會自動重新把新創建出來的mListener給綁定到ListenerCollector中,但是當activity被銷毀的時候,mListener卻無法被回收了。 ## 4)Heap Viewer Walkthrough 下圖演示了Android Tools里面的Heap Viewer的功能,我們可以看到當前進程中的Heap Size的情況,分別有哪些類型的數據,占比是多少。 ![](https://box.kancloud.cn/2015-08-21_55d6c597e65aa.png) ## 5)Understanding Memory Churn **Memory Churn內存抖動**,內存抖動是因為在短時間內大量的對象被創建又馬上被釋放。瞬間產生大量的對象會嚴重占用Young Generation的內存區域,當達到閥值,剩余空間不夠的時候,會觸發GC從而導致剛產生的對象又很快被回收。即使每次分配的對象占用了很少的內存,但是他們疊加在一起會增加Heap的壓力,從而觸發更多其他類型的GC。這個操作有可能會影響到幀率,并使得用戶感知到性能問題。 ![](https://box.kancloud.cn/2015-08-21_55d6c59f099cf.png) 解決上面的問題有簡潔直觀方法,如果你在**Memory Monitor**里面查看到短時間發生了多次內存的漲跌,這意味著很有可能發生了內存抖動。 ![](https://box.kancloud.cn/2015-08-21_55d6c5ab31234.png) 同時我們還可以通過**Allocation Tracker**來查看在短時間內,同一個棧中不斷進出的相同對象。這是內存抖動的典型信號之一。 當你大致定位問題之后,接下去的問題修復也就顯得相對直接簡單了。例如,你需要避免在for循環里面分配對象占用內存,需要嘗試把對象的創建移到循環體之外,自定義View中的onDraw方法也需要引起注意,每次屏幕發生繪制以及動畫執行過程中,onDraw方法都會被調用到,避免在onDraw方法里面執行復雜的操作,避免創建對象。對于那些無法避免需要創建對象的情況,我們可以考慮對象池模型,通過對象池來解決頻繁創建與銷毀的問題,但是這里需要注意結束使用之后,需要手動釋放對象池中的對象。 ## 6)Allocation Tracker 關于Allocation Tracker工具的使用,不展開了,參考下面的鏈接: * [http://developer.android.com/tools/debugging/ddms.html#alloc](http://developer.android.com/tools/debugging/ddms.html#alloc) * [http://android-developers.blogspot.com/2009/02/track-memory-allocations.html](http://android-developers.blogspot.com/2009/02/track-memory-allocations.html) ## 7)Improve Your Code To Reduce Churn 下面演示一個例子,如何通過修改代碼來避免內存抖動。優化之前的內存檢測圖: ![](https://box.kancloud.cn/2015-08-21_55d6c5aec4af0.png) 定位代碼之后,修復了String拼接的問題: ![](https://box.kancloud.cn/2015-08-21_55d6c5b04d1ea.png) 優化之后的內存監測圖: ![](https://box.kancloud.cn/2015-08-21_55d6c5b4e2f4c.png) ## 8)Recap 上面提到了三種測量內存的工具,下面再簡要概括一下他們各自的特點: * **Memory Monitor:**跟蹤整個app的內存變化情況。 * **Heap Viewer:**查看當前內存快照,便于對比分析哪些對象有可能發生了泄漏。 * **Allocation Tracker:**追蹤內存對象的來源。 **Notes:**關于更多內存優化,這里還有一篇文章,請點擊[這里](http://hukai.me/android-training-managing_your_app_memory/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看