㈠ android App內存優化
內存優化就是對內存問題的一個預防和解決,做內存優化能讓應用掛得少、活得好和活得久。
掛的少:
「掛」指的是 Crash,內存問題導致 Crash 的具體表現就是內存溢出異常 OOM。
活得好:
活得好指的是使用流暢,Android 中造成界面卡頓的原因有很多種,其中一種就是由內存問題引起的。內存問題之所以會影響到界面流暢度,是因為垃圾回收(GC,Garbage Collection),在 GC 時,所有線程都要停止,包括主線程,當 GC 和繪制界面的操作同時觸發時,繪制的執行就會被擱置,導致掉幀,也就是界面卡頓。
活得久:
活得久指的是我們的應用在後台運行時不會被幹掉。Android 會按照特定的機制清理進程,清理進程時優先會考慮清理後台進程。清理進程的機制就是LowMemoryKiller。在 Android 中不同的進程有著不同的優先順序,當兩個進程的優先順序相同時,低殺會優先考慮幹掉消耗內存更多的進程。也就是如果我們應用佔用的內存比其他應用少,並且處於後台時,我們的應用能在後台活下來,這也是內存優化為我們應用帶來競爭力的一個直接體現。
內存佔用是否越少越好?
當系統 內存充足 的時候,我們可以多用 一些獲得更好的性能。當系統 內存不足 的時候,我們希望可以做到 」用時分配,及時釋放「。內存優化並不能一刀切。
我們都知道,應用程序的內存分配和垃圾回收都是由Android虛擬機完成的,在Android 5.0以下,使用的是Dalvik虛擬機,5.0及以上,則使用的是ART虛擬機。
Android虛擬機Dalvik和ART
1、內存區域劃分
詳細請看以下兩篇文章(建議全看):
java內存四大區_JVM內存區域劃分
Android 內存機制
2、內存回收
垃圾收集的標記演算法(找到垃圾):
垃圾收集演算法(回收垃圾):
引用類型:強引用、軟引用、弱引用、虛引用
對象的有效性=可達性+引用類型
JAVA垃圾回收機制-史上最容易理解看這一篇就夠了
Android:玩轉垃圾回收機制與分代回收策略
android中還存在低殺機制,這種情況屬於系統整機內存不足,直接把應用進程殺掉的情況。
Android後台殺死系列:LowMemoryKiller原理
1、內存溢出
系統會給每個App分配內存空間也就是heap size值,當app佔用的內存加上申請的內存超過這個系統分配的內存限額,最終導致OOM(OutOfMemory)使程序崩潰。
通過命令 getprop |grep dalvik.vm.heapsize 可以獲取系統允許的最大
注意:在設置了heapgrowthlimit的狀況下,單個進程可用最大內存為heapgrowthlimit值。在android開發中,若是要使用大堆,須要在manifest中指定android:largeHeap為true,這樣dvm heap最大可達heapsize。
關於heapsize & heapgrowthlimit
2、內存泄漏
Android系統虛擬機的垃圾回收是通過虛擬機GC機制來實現的。GC會選擇一些還存活的對象作為內存遍歷的根節點GC Roots,通過對GC Roots的可達性來判斷是否需要回收。內存泄漏就是 在當前應用周期內不再使用的對象被GC Roots引用,造成該對象無法被系統回收,以致該對象在堆中所佔用的內存單元無法被釋放而造成內存空間浪費,使實際可使用內存變小。簡言之,就是 對象被持有導致無法釋放或不能按照對象正常的生命周期進行釋放。
Android常見內存泄漏匯總
3、內存抖動
指的是在短時間內大量的新對象被實例化,運行時可能無法承載這樣的內存分配,在這種情況下就會導致垃圾回收事件被大量調用,影響到應用程序的UI和整體性能,最終可能導致卡頓和OOM。
常見情況:在一些被頻繁調用的方法內不斷地創建對象。例如在View 的onDraw方法內new 一些新的對象。
注意內存抖動也會導致 OOM,主要原因有如下兩點:
1、Android Studio Profiler
作用
優點
內存抖動問題處理實戰
理解內存抖動的概念的話,我們就能明白只要能找到抖動過程中所產生的對象及其調用棧,我們就能解決問題,剛好Android Studio 的Porfiler裡面的Memory工具就能幫我們記錄下我們操作過程中或靜止界面所產生的新對象,並且能清晰看到這些對象的調用棧。
選擇Profile 中 的Memory ,選擇 Record Java/Kotlin allocations,再點擊Record開始記錄, Record Java/Kotlin allocations 選項會記錄下新增的對象。
操作完成之後,點擊如圖所示的紅腦按鈕,停止記錄。
停止記錄後,我們就可以排序(點擊 Allocations可以排序)看看哪些對象或基本類型在短時間被頻繁創建多個,點擊這些新增的對象就可以看到它的完成的調用鏈了,進而就找找到導致內存抖動的地方在哪裡了。
2、利用DDMS 和 MAT(Memory Analyzer tool)來分析內存泄漏
我們利用工具進行內存泄漏分析主要是用對比法:
a.先打開正常界面,不做任何操作,先抓取一開始的堆文件。
b.一頓胡亂操作,回到原來操作前的界面。主動觸發一兩次GC,過10秒再抓取第二次堆文件。
c.通過工具對比,獲取胡亂操作後新增的對象,然後分析這些新增的對象。
DDMS作用:抓取堆文件,主動觸發GC。(其實也是可以用Android Studio 的Profile裡面的Memory工具來抓取堆文件的,但是我這邊在利用Profile 主動觸發gc 的時候會導致程序奔潰,也不知道是不是手機的問題,所以沒用Android Studio的Profiler)
MAT作用:對堆文件進行對比,找到多出的對象,找到對象的強引用調用鏈。
以下是詳細的過程:
步驟1.打開DDMS,選擇需要調試的應用,打開初始界面,點擊下圖的圖標(Dump Hprof File)先獲取一次堆文件。
步驟2.對應用隨便操作後,回到一開始的界面,先多觸發幾次GC ,點擊下圖的圖標(Cause Gc)來主動觸發GC,然後再次點擊 Dump Hprof File 圖標來獲取堆文件。
步驟3.通過Android Studio Profile 或者 DDMS mp 的堆文件無法在MAT 打開,需要藉助android sdk包下的一個工具hprof-conv.exe來轉換。
格式為 hprof-conv 舊文件路徑名 要轉換的名稱;
例如:hprof-conv 2022-04-13_17-54-40_827.hprof change.hprof
步驟4.把兩份堆文件導入MAT,然後選擇其中第二次獲取的堆文件,點擊 如圖所示的 Histogram查看。
步驟5.點擊下圖圖標,Compare To Another Heap Dump ,選擇另一份堆文件。
6.會得出下圖所示的 Hitogram 展示,我們主要看Objects 這一列。 如下圖所示 「+ 2」 則代表前面兩份堆文件對比,這個對象多了兩個,我們主要就是要分析這些多了出來,沒有被回收的對象。
7.加入我們從增加的對象中,看到了MainActivity ,則需要從一開始打開的Hitogram 展示裡面找到這個對象的調用棧。如下圖所示,搜索MainActivity
8.看到下圖所示解僱,然後滑鼠右鍵點擊下圖紅色圈圈著的MainActivity ,選擇 Merger Shortest Paths to Gc Roots ,再選擇 exclude all phantom/weak/soft etc.references ,就可以看到這個MainActivity 對象的強引用鏈,至此我們就可以找到MainActivity對象是被什麼引用導致無法回收了。
3、內存泄露檢測神器之LeakCanary(線下集成)
自行學習了解,接入簡單,使用簡單,基本可以解決大部分內存泄漏問題。
github地址 : https://github.com/square/leakcanary/
學習地址 : https://square.github.io/leakcanary/changelog/#version-22-2020-02-05
針對內存抖動的建議:
針對內存泄漏問題的建議:
針對內存溢出問題的建議(主要就是要減少內存佔用):
建議參考:
深入探索 Android 內存優化(煉獄級別)
對於 優化的大方向,我們應該優先去做見效快的地方,主要有以下三部分:內存泄漏、內存抖動、Bitmap。完善監控機制也是我們的重點,能幫助我們對內存問題快速分析和處理。
參考:
深入探索 Android 內存優化(煉獄級別)
㈡ 性能優化:Android中Bitmap內存大小優化的幾種常見方式
Android中優化Bitmap內存大小是提升應用性能的關鍵步驟。Bitmap佔用內存大小的計算遵循其配置(Bitmap.Config)和大小。默認配置下,每個像素佔用4位元組。因此,優化主要通過調整寬度、高度或配置來減少內存消耗。
優化策略包括:
1. **采樣率壓縮**:通過改變采樣率來縮小Bitmap大小,以此降低內存需求。例如,將原圖大小從640px * 360px縮小至1/4,內存佔用相應減少至原來的1/16。該方法適用於原有圖片寬高過大、目標尺寸較小的情況,避免了不必要的內存浪費。
2. **矩陣壓縮**:使用Bitmap.createBitmap或Bitmap.createScaledBitmap方法進行縮放。設定縮放比例後,內存佔用減少至原圖的1/100。適用於原圖大小和目標Bitmap尺寸已知的情況。
3. **更改配置**:將默認的Bitmap.Config.ARGB_8888改為佔用位元組更少的配置,如ARGB_4444或RGB_565。對於非透明度要求高的圖像,使用RGB_565更為合適。此方法適用於對圖像解析度要求不高的場景。
4. **質量壓縮**:通過Bitmap.compress方法調整quality參數來減小生成的位元組流大小,而不影響Bitmap內存佔用。此方法在保持圖像質量的同時,減小了圖像的位深、透明度等,適用於需要傳遞二進制圖片數據的場景,如微信分享。
在實際開發中,應根據具體需求選擇合適的優化策略。優化Bitmap內存大小不僅能夠提升應用的性能和響應速度,還能有效避免內存溢出問題。
㈢ 提升Android手機運行內存教程
隨著智能手機的不斷發展以及用戶需求的不斷增加,手機的運行內存(RAM)的大小已經從MB過渡到了GB容量,作為用戶的我們只是知道運行內存越大越好,而運行內存到底有什麼用你知道么?接下來是我為大家收集的提升Android手機運行內存教程,希望能幫到大家。
提升Android手機運行內存教程
知識小科普
無應用運行時內存佔用已近半
這個時候就又到了筆者給大家科普的時候了。RAM全稱Random Access Memory,我們都習慣稱之為運行內存,又稱隨機存儲器。其是與CPU直接交換數據的內部存儲器,也叫主存(內存)。它可以隨時讀寫,並且速度很快,通常作為系統或正在運行程序的臨時數據存儲媒介。
為啥安卓手機更吃內存
看到這你可能深深的認為RAM還是越大越好,對沒錯筆者也是這么認為的。縱觀安卓手機的發展,RAM已經從最初的128MB發展到了現在的6GB(消息稱8GB已經在路上),而蘋果從最初的128MB至今RAM也不過才發展到2GB而已,但仍然可以流暢運行,這又是為何呢?
iOS VS Android(圖片引自antutu)
這就完全要歸結於安卓和蘋果不同的內存運行機制。安卓系統在運行一個程序時:CPU開始計算-內存開始緩存-再讀取目標文件開始計算,當結束程序時CPU計算完畢但內存仍然有部分緩存佔用。而蘋果就不同當CPU開始運算後就會收集所有內存為應用運行進行緩存,在結束應用時會釋放全部內存。
用戶的內存不足解決之道
對於一般用戶來說就是安裝各類清理軟體,卸載多餘不常用APP,軟體關閉後及時清理後台。目前許多手機中還加入了後台應用管理的功能並提供一鍵清理選項,實在受不了的時候就對手機進行一次出廠化設置。
手機中自帶的許可權管理應用
對於安卓有一定了解的用戶,則會選擇精簡版的ROM來進行刷機(一般情況下系統的精簡度是和流暢性成正比的),並通過ROOT獲取許可權,從根本控制軟體的自啟及對內存的佔用。
各類刷機軟體中都提供精簡版ROM一鍵刷機和一鍵ROOT(圖片引自romjd)
而那些動手能力極強的用戶還會選擇一些特別的方法,比如通過創建Swap(交換分區)來解決,當用戶的實體內存不足時便會調用這部分虛擬內存來運行應用。
Linux中的Swap即交換分區,類似於Windows的虛擬內存,就是當內存不足的時候,把一部分硬碟空間虛擬成內存使用,從而解決內存容量不足的情況。而Android正是基於Linux研發的操作系統,所以也可以使用Swap分區來提升系統運行效率。
對於安卓手機如何創建Swap的具體過程筆者就不做過多介紹,不過首先你的手機內核需要支持Swap,並且已ROOT,可以利用內置存儲或內存卡(需注意卡片讀寫速度)進行製作,詳細方法及所需軟體請執行網路。
看了“提升Android手機運行內存教程”還想看:
1. 安卓手機運行內存不夠用的解決方法
2. 怎樣能刷運行內存
3. 安卓手機運行內存太小怎麼優化
4. 怎樣擴大手機內部內存
5. 怎樣擴展手機最大內存