性能優(yōu)化->虛擬機原理 怎么分析堆內存 內存泄露和內存溢出的原因 怎么做內存管理
JVM類加載機制
Java內存區(qū)域與內存溢出
垃圾回收算法
!Android GC 原理探究
Android 內存泄漏總結
內存溢出(OOM)
Android關于OOM的解決方案
1、什么是OOM
指Out of memory(內存溢出),應用當前占用的內存加上我們申請的內存資源超過了虛擬機對該應用的最大內存限制就會拋出Out of memory異常
程序所需要的內存超過了系統(tǒng)所能分配的內存(包括動態(tài)擴展)的上限。
2、OOM相關概念
- 內存溢出:指程序在申請內存時,沒有足夠的空間供其使用
- 內存泄漏:指程序分配出去的內存不再使用,但無法進行回收
- 內存抖動:指程序短時間內大量創(chuàng)建對象,然后回收的現象
3、解決OOM
Bitmap相關
- 圖片壓縮
- 加載縮略圖
- 在滾動時不加載圖片
- 及時回收Bitmap
- 使用inBitmap屬性(將該屬性設為true可以將BaseMemoryCache和LruMemoryCache結合使用, 先取Lru沒有再取Base,因Base中的Cache很可能被回收)
- 捕獲異常
其他相關
- listview重用convertView、使用lru
- 避免在onDraw方法中執(zhí)行對象的創(chuàng)建
- 謹慎使用多進程
內存泄漏
1、Java中引起內存泄漏的主要原因
內存泄漏是指分配出去的內存沒有被回收回來,由于失去了對該內存區(qū)域的控制,因而造成了資源的浪費。Java中一般不會產生內存泄漏,因為有垃圾回收器自動回收垃圾,但這也不絕對,當我們new了對象,并保存了其引用,但是后面一直沒用它,而垃圾回收器又不會去回收它,這就會造成內存泄漏。
長生命周期的對象持有短生命周期對象的引用
2、Java內存分配策略
靜態(tài)存儲區(qū):又稱方法區(qū),主要存儲全局變量和靜態(tài)變量,在整個程序運行期間都存在
棧區(qū):方法體的局部變量會在棧區(qū)得到分配空間,并在方法執(zhí)行結束后自動釋放變量得到的資源
堆區(qū):保存動態(tài)產生的數據,如:new出來的對象和數組,在不使用的時候由Java回收器自動回收
3、Android解決內存泄漏的例子
- 單例造成的內存泄漏:使用context.getApplicationContext()作為單例的context
- 匿名內部類造成的內存泄漏:由于非靜態(tài)內部類持有匿名外部類的引用,必須將內部類設置為static
- Handler造成的內存泄漏:使用static的Handler內部類,同時在實現內部類中持有Context的弱引用
- 避免使用static變量:由于static變量會跟Activity生命周期一致,當Activity退出后,被后臺回收時,static變量是不安全,所以也要管理好static變量的生命周期
- 資源未關閉造成的內存泄漏:比如Socket、Broadcast、Cursor、Bitmap、ListView等,使用完后要關閉
- 【AsyncTask造成的內存泄漏】:由于非靜態(tài)內部類持有匿名內部類的引用而造成內存泄漏,可以通過AsyncTask內部持有外部Activity的弱引用同時改為靜態(tài)內部類或在onDestroy()中執(zhí)行AsyncTask.cancel()進行修復
如何使用leakCanary
內存管理
1、Android內存管理機制
分配機制
管理機制
2、內存管理機制的特點
更少的占用內存
在合適的時候,合理的釋放系統(tǒng)資源
在系統(tǒng)內存緊張的時候,能釋放掉大部分不重要的資源
能合理的在特定生命周期中,保存或還原重要數據
3、內存優(yōu)化方法
Service完成任務后應停止它,或用IntentService(因為可以自動停止服務)代替Service
在UI不可見的時候,釋放其UI資源
在系統(tǒng)內存緊張的時候,盡可能多的釋放非重要資源
避免濫用Bitmap導致內存浪費
避免使用依賴注入框架
使用針對內存優(yōu)化過的數據容器
使用ZIP對齊的APK
使用多進程
JAVA內存區(qū)域
- 程序計數器
- Java虛擬機棧
- 本地方法棧
- Java堆
- 方法區(qū)
- 運行時常量池
- 直接內存
其它內存/JVM相關
ART代表Android Runtime,是google開發(fā)的執(zhí)行效率更高更省電的替代運行時,其處理應用程序執(zhí)行的方式完全不同于Dalvik。ART完全改變了這套做法,在應用安裝的時候就預編譯字節(jié)碼到機器語言,這一機制叫Ahead-Of-Time(AOT)編譯。在移除解釋代碼這一過程后,應用程序執(zhí)行將更有效率,啟動更快。
Dalvik是Google公司自己設計用于Android平臺的Java虛擬機,是依靠一個Just-In-Time(JIT)編譯器去解釋字節(jié)碼。開發(fā)者編譯后的應用代碼需要通過一個解釋器在用戶的設備上運行,這一機制并不高效,但讓應用能更容易在不同硬件和架構上運行。它可以支持已轉換為.dex(即Dalvik Executable)格式的Java應用程序的運行,.dex格式是專為Dalvik應用設計的一種壓縮格式,適合內存和處理器速度有限的系統(tǒng)。Dalvik經過優(yōu)化,允許在有限的內存中同時運行多個虛擬機的實例,并且每一個Dalvik應用作為獨立的Linux進程執(zhí)行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
ART優(yōu)點:
系統(tǒng)性能的顯著提升
應用啟動更快、運行更快、體驗更流暢、觸感反饋更及時
更長的電池續(xù)航能力
支持更低的硬件
ART缺點:
更大的存儲空間占用,可能會增加10%-20%
更長的應用安裝時間