android的內存優化
Ⅰ android 內存優化有哪些方法
增加優化代碼,在system/build.prop添加指定代碼(有變磚風險),樓主慎重操作,
或者刷內核,當然也有一些其他的方法,不過對於安卓手機就這樣,除非換手機,畢竟安卓只能拼配置
Ⅱ android開發內存優化之如何有效避免oom
減小對象的內存佔用
內存對象的重復利用
避免對象的內存泄露
內存使用策略優化
設計風格很大程度上會影響到程序的內存與性能,相對來說,如果大量使用類似Material Design的風格,不僅安裝包可以變小,還可以減少內存的佔用,渲染性能與載入性能都會有一定的提升。
內存優化並不就是說程序佔用的內存越少就越好,如果因為想要保持更低的內存佔用,而頻繁觸發執行gc操作,在某種程度上反而會導致應用性能整體有所下降,這里需要綜合考慮做一定的權衡。
Android的內存優化涉及的知識面還有很多:內存管理的細節,垃圾回收的工作原理,如何查找內存泄漏等等都可以展開講很多。OOM是內存優化當中比較突出的一點,盡量減少OOM的概率對內存優化有著很大的意義。
Ⅲ 針對Android的性能優化集中哪些方面
一、概要:
本文主要以Android的渲染機制、UI優化、多線程的處理、緩存處理、電量優化以及代碼規范等幾方面來簡述Android的性能優化
二、渲染機制的優化:
大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。
Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染, 如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。
*關於JobScheler的更多知識可以參考http://hukai.me/android-training-course-in-chinese/background-jobs/scheling/index.html
七、代碼規范
1)for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。
2)明白垃圾回收機制,避免頻繁GC,內存泄漏,OOM(有機會專門說)
3)合理使用數據類型,StringBuilder代替String,少用枚舉enum,少用父類聲明(List,Map)
4)如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程創建開銷。
5)你要知道單例的好處,並正確的使用它。
6)多用常量,少用顯式的"action_key",並維護一個常量類,別重復聲明這些常量。
7)如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,工廠模式,觀察者模式,這些能幫助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一發而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。
8)View中設置緩存屬性.setDrawingCache為true.
9)cursor的使用。不過要注意管理好cursor,不要每次打開關閉cursor.因為打開關閉Cursor非常耗時。Cursor.require用於刷cursor.
10)採用SurfaceView在子線程刷新UI,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)
11)採用JNI,將耗時間的處理放到c/c++層來處理
12)有些能用文件操作的,盡量採用文件操作,文件操作的速度比資料庫的操作要快10倍左右
13)懶載入和緩存機制。訪問網路的耗時操作啟動一個新線程來做,而不要再UI線程來做
14)如果方法用不到成員變數,可以把方法申明為static,性能會提高到15%到20%
15)避免使用getter/setter存取field,可以把field申明為public,直接訪問
16)私有內部類要訪問外部類的field或方法時,其成員變數不要用private,因為在編譯時會生成setter/getter,影響性能。可以把外部類的field或方法聲明為包訪問許可權
17)合理利用浮點數,浮點數比整型慢兩倍
18)針對ListView的性能優化,ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。ListView中getView是性能是關鍵,這里要盡可能的優化。
getView方法中要重用view;getView方法中不能做復雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的性能
19)不用new關鍵詞創建類的實例,用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。
clone()方法不會調用任何類構造函數。在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現:
20)public static Credit getNewCredit() {
return new Credit();
}
改進後的代碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}
上面的思路對於數組處理同樣很有用。
21)乘法和除法
考慮下面的代碼:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
用移位操作替代乘法操作可以極大地提高性能。下面是修改後的代碼:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
22)ViewPager同時緩存page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。
23)每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預載入數據,以免造成浪費
24)提高下載速度:要控制好同時下載的最大任務數,同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)
25)提供載入速度:讓服務端提供不同解析度的圖片才是最好的解決方案。還有合理使用內存緩存,使用開源的框架
引用:Android性能優化的淺談
Ⅳ 安卓手機優化內存怎麼設置
手機內存已滿的解決方法:
1、卸載不常用軟體,
2、清理一下緩存垃圾、
3、刪除過期緩存的視頻和音樂文件,
4、必要時恢復出廠設置和刷機。手機的內存容量是和手機使用時間成正比的,使用時間越長內存容量越大,例如一款瀏覽器軟體剛下載是十幾兆,過一段由於數據的積累會增值到幾百兆,這樣就出現內存已滿的提示。如果不及時處理手機就會卡慢頓了。
Ⅳ android 內存優化
android 內存優化?1.內存模型與分布
我們知道android應用大多是使用java語言進行開發的,這就需要我們了解java的內存模型,此外在android中的應用都是基於Dalvik 虛擬機或者ART虛擬機,那麼對這些虛擬機的內存分布也應該有所了解。
Java內存分布模型
上圖是常見的java虛擬機的內存分布圖:
方法區:主要存儲虛擬機載入的類信息,常量,靜態變數,及時編譯器編譯後的代碼等數據。內存優化時這一部分主要考慮是不是載入了很多不必要的第三方庫。這部分的內存減少主要是常量池的回收和類的卸載(類卸載條件:無引用,類載入器可卸載)
堆:幾乎所有的對象都在這個區域產生,該區域屬於線程共享的區域,所以寫代碼時更要注意多線程安全。這個內存區域的大小變化主要是對象的創建和回收,比如:如果短時間內有大量的對象創建和回收,可能會造成內存抖動,如果對象創建之後一直回收不掉,則會導致內存泄漏,嚴重的內存泄漏會導致頻繁的gc,從而是界面卡頓。
虛擬機棧:這個區域描述的是java方法執行的內存模型,我們常說的方法棧的入棧就是將方法的棧幀存儲到虛擬機棧,這個區域是線程私有的,其生命周期就是線程的生命周期。也就是說每個線程都會有,默認一個線程的線程棧大小是1M,這不包括在方法中產生的其他對象的大小。這一塊我們能控制的就是線程的數量,特別是程序中沒有使用線程池或者使用的多個第三方庫都帶有線程池的情況。
本地方法棧:同虛擬機棧的作用非常類似,是為虛擬機執行native方法服務的,所以需要注意的地方也和虛擬機棧一樣,特別是使用了第三方so的情況
程序計數器:當前線程執行的虛擬機位元組碼的行號記錄器,佔用的內存較小,可以不考慮
2.內存限制
android是基於linux系統的,android中的進程分為兩種:
1.native進程:採用C/C++實現,不包含dalvik實例的linux進程,/system/bin/目錄下面的程序文件運行後都是以native進程形式存在的
2.java進程:實例化了dalvik虛擬機實例的linux進程,進程的入口main函數為java函數。dalvik虛擬機實例的宿主進程是fork()系統調用創建的linux進程,所以每一個android上的java進程實際上就是一個linux進程,只是進程中多了一個dalvik虛擬機實例
我們知道,操作系統對進程的內存是有限制的,而且操作系統對dalvik虛擬機自身的堆內存大小也是有限制的。可以通過如下命令查看限制大小:
adb shell getprop | grep dalvik.vm.heapgrowthlimit
可以在Androidmanifest文件中application節點加入android:largeHeap=「true」來增加其dalvik虛擬機中堆的大小
我們常說的堆大小其實是包涵兩部分的,一是java的堆,而是native的堆,java堆中主要是一下java對象,由 C/C++申請的內存空間則在native堆中,也有一些對象需要結合native和java堆共同完成,比如bitmap,bitmap分為bitmap對象和其中存儲的像素值,對象分配在java堆,而存儲的像素值則根據版本不同存儲的位置也不同,api 11 - api 25是存儲在java堆中的,其他版本是存儲在native堆中的
3.內存泄漏
常見的內存泄漏:
1.靜態引用(自身代碼和第三方代碼)
2.集合內引用
3.Handler消息未清除
4.非靜態的內部類中持有外部內的應用
5.匿名內部類/非靜態內部類和非同步線程
檢查的方式:
我這里使用的是leakcanary,一般簡單的內存泄漏可以直接在leakcanary中查到引用鏈路,不能查看的我是使用MAT來分析的
當前內存信息
上圖中各項詳細的指標的意義可以在這里查到,這里主要佔比比較大的幾個區域:
allocated:表示app內分配的java的對象數,從當前數值可以看出程序內可能存在過多創建對象的情況,比如string對象
Native:從 C 或 C++ 代碼分配的對象內存,頻繁進出相關頁面發現native堆的大小並沒有減小,說明存在c/c++層的內存泄漏
Code:您的應用用於處理代碼和資源(如 dex 位元組碼、已優化或已編譯的 dex 碼、.so 庫和字體)的內存。這個區域能優化的就是移除不需要的so庫,懶載入使用so庫,移除無用代碼(import,方法和類)
4.優化實踐
了解了android中的內存分布和泄漏相關,接下來就是結合自身業務進行內存優化了,如下:
1.先解決程序中內存佔用較大的業務模塊中的內存泄漏,不熟悉MAT的使用的可以看看這個
2.移除程序中多餘的代碼和引用,這里使用默認的lint檢測再配合shrinkResources來刪除無效資源
3.優化圖片,保證圖片放置在合理的文件夾,根據View大小載入合適的圖片大小,根據手機狀態配置bitmap和回收策略
4.優化對象創建,比如string,使用對象池等
Ⅵ 如何優化android 手機內存的軟體
安卓程序並不能完完全全變得像iOS那樣流程,這是安卓本身的設計的限制。安卓程序的後台運行是真的後台運行,就算你關了程序,但是程序還是會在後台運行的。所以,安卓註定會越用越卡,這是避免不了的,我們能做的只有盡量優化一下,以下是一些建議。
1.優化APP設計。減少代碼冗餘.比如重復性的代碼可以寫在函數里,每次只需調用同一塊代碼.更不要為實現一個功能而圖方便引入一個龐大的庫(有很多功能可能用不上,卻降低執行代碼的效率)
2.用戶要經常釋放內存。某些功能在用不上時絕對不要霸佔著寶貴的內存空間。
3.多了解一下計算機工作原理的知識,理解實現同一功能的兩段代碼背後運行效率的區別。
Ⅶ android為什麼要內存優化
android為什麼要內存優化是為了防止Android的內存溢出
Android的內存溢出是如何發生的?
Android的虛擬機是基於寄存器的Dalvik,它的最大堆大小一般是16M,有的機器為24M。因此所能利用的內存空間是有限的。如果內存佔用超過了一定的水平就會出現OutOfMemory的錯誤。
為什麼會出現內存不夠用的情況呢?原因主要有兩個:由於程序的失誤,長期保持某些資源(如Context)的引用,造成內存泄露,資源造成得不到釋放。
保存了多個耗用內存過大的對象(如Bitmap),造成內存超出限制。
在android的開發中,要時刻主要內存的分配和垃圾回收,因為系統為每一個dalvik虛擬機分配的內存是有限的,在google的G1中,分配的最大堆大小隻有16M,後來的機器一般都為24M,實在是少的可憐。這樣就需要在開發過程中要時刻注意。不要因為自己的代碼問題而造成OOM錯誤。
Android的優化方式
Android的程序由Java語言編寫,所以Android的內存管理與Java的內存管理相似。程序員通過new為對象分配內存,所有對象在java堆內分配空間;然而對象的釋放是由垃圾回收器來完成的。C/C++中的內存機制是「誰污染,誰治理」,java的就比較人性化了,給我們請了一個專門的清潔工(GC)。
那麼GC怎麼能夠確認某一個對象是不是已經被廢棄了呢?Java採用了有向圖的原理。Java將引用關系考慮為圖的有向邊,有向邊從引用者指向引用對象。線程對象可以作為有向圖的起始頂點,該圖就是從起始頂點開始的一棵樹,根頂點可以到達的對象都是有效對象,GC不會回收這些對象。如果某個對象 (連通子圖)與這個根頂點不可達(注意,該圖為有向圖),那麼認為這個(這些)對象不再被引用,可以被GC回收
Ⅷ 如何優化app的運行內存佔用問題
下面的方法可以優化app的運行內存:
1、內存資源緊張時釋放內存
在應用生命周期的任何階段onTrimMemory()回調方法都可以告訴你設備的內存越來越低的情況,
你可以根據該方法推送的內存緊張級別來釋放資源.
2、使用優化後的數據容器
利用 Android 框架優化後的數據容器, 比如SparseArray,SparseBooleanArray和LongSparseArray.
傳統的 HashMap 在內存上的實現十分的低效因為它需要為 map 中每一項在內存中建立映射關系. 另外,SparseArray類非常高效因為它避免系統中需要自動封箱(autobox)的key。
3、使用保守的Service
如果你的應用需要使用 service 在後台執行業務功能, 除非是一直在進行活動的工作(比如每隔幾秒向伺服器端請求數據之類)否則不要讓它一直保持在後台運行. 並且, 當你的service執行完成但是停止失敗時要小心service導致的內存泄露問題.
4、當心抽象代碼
通常來說, 使用簡單的抽象是一種好的編程習慣, 因為一定程度上的抽象可以提供代碼的伸縮性和可維護性. 然而抽象會帶來非常顯著的開銷: 需要執行更多的代碼, 需要更長時間和更多的運行內存把代碼映射到內存中, 所以如果抽象沒有帶來顯著的效果就盡量避免.
那麼如何查看APP運行內存佔多少?
手機查看運行內存的方法:
1.部分手機內置內存管理器/智能管理器,開啟該應用可查看內存使用情況。
2.部分機器:長按Home鍵-進入任務管理器-RAM狀態-查看即可。
提示:不同型號手機查看路徑可能略有不同。
Ⅸ 在Android開發中,有哪些好的內存優化方式
1. 使用更加輕量的數據結構
例如,我們可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統數據結構。通常的HashMap的實現方式更加消耗內存,因為它需要一個額外的實例對象來記錄Mapping操作。另外,SparseArray更加高效,在於他們避免了對key與value的自動裝箱(autoboxing),並且避免了裝箱後的解箱。
2. 避免在Android裡面使用Enum
Android官方培訓課程提到過「Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.」,具體原理請參考《Android性能優化典範(三)》,所以請避免在Android裡面使用到枚舉。
3. 減小Bitmap對象的內存佔用
Bitmap是一個極容易消耗內存的大胖子,減小創建出來的Bitmap的內存佔用可謂是重中之重,,通常來說有以下2個措施:
inSampleSize:縮放比例,在把圖片載入內存之前,我們需要先計算出一個合適的縮放比例,避免不必要的大圖載入。
decode format:解碼格式,選擇ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差異
4.Bitmap對象的復用
縮小Bitmap的同時,也需要提高BitMap對象的復用率,避免頻繁創建BitMap對象,復用的方法有以下2個措施
LRUCache : 「最近最少使用演算法」在Android中有極其普遍的應用。ListView與GridView等顯示大量圖片的控制項里,就是使用LRU的機制來緩存處理好的Bitmap,把近期最少使用的數據從緩存中移除,保留使用最頻繁的數據,
inBitMap高級特性:利用inBitmap的高級特性提高Android系統在Bitmap分配與釋放執行效率。使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經存在的內存區域,新解碼的Bitmap會嘗試去使用之前那張Bitmap在Heap中所佔據的pixel data內存區域,而不是去問內存重新申請一塊區域來存放Bitmap。利用這種特性,即使是上千張的圖片,也只會僅僅只需要佔用屏幕所能夠顯示的圖片數量的內存大小
4. 使用更小的圖片
在涉及給到資源圖片時,我們需要特別留意這張圖片是否存在可以壓縮的空間,是否可以使用更小的圖片。盡量使用更小的圖片不僅可以減少內存的使用,還能避免出現大量的InflationException。假設有一張很大的圖片被XML文件直接引用,很有可能在初始化視圖時會因為內存不足而發生InflationException,這個問題的根本原因其實是發生了OOM。
5.StringBuilder
在有些時候,代碼中會需要使用到大量的字元串拼接的操作,這種時候有必要考慮使用StringBuilder來替代頻繁的「+」。
6.避免在onDraw方法裡面執行對象的創建
類似onDraw等頻繁調用的方法,一定需要注意避免在這里做創建對象的操作,因為他會迅速增加內存的使用,而且很容易引起頻繁的gc,甚至是內存抖動。
7. 避免對象的內存泄露
類的靜態變數持有大數據對象
靜態變數長期維持到大數據對象的引用,阻止垃圾回收。
非靜態內部類存在靜態實例
非靜態內部類會維持一個到外部類實例的引用,如果非靜態內部類的實例是靜態的,就會間接長期維持著外部類的引用,阻止被回收掉。
資源對象未關閉
資源性對象比如(Cursor,File文件等)往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們, 以便它們的緩沖及時回收內存。它們的緩沖不僅存在於java虛擬機內,還存在於java虛擬機外。 如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內存泄露。
解決辦法: 比如SQLiteCursor(在析構函數finalize(),如果我們沒有關閉它,它自己會調close()關閉), 如果我們沒有關閉它,系統在回收它時也會關閉它,但是這樣的效率太低了。 因此對於資源性對象在不使用的時候,應該調用它的close()函數,將其關閉掉,然後才置為null. 在我們的程序退出時一定要確保我們的資源性對象已經關閉。 程序中經常會進行查詢資料庫的操作,但是經常會有使用完畢Cursor後沒有關閉的情況。如果我們的查詢結果集比較小, 對內存的消耗不容易被發現,只有在常時間大量操作的情況下才會復現內存問題,這樣就會給以後的測試和問題排查帶來困難和風險,記得try catch後,在finally方法中關閉連接
Handler內存泄漏
Handler作為內部類存在於Activity中,但是Handler生命周期與Activity生命周期往往並不是相同的,比如當Handler對象有Message在排隊,則無法釋放,進而導致本該釋放的Acitivity也沒有辦法進行回收。
Ⅹ 安卓手機運行內存太小怎麼進行優化
安卓系統手機為智能機器,和電腦一樣,為了保證手機正常使用,會自動開啟部分程序進程(不是程序),當您清除之後,進程還是會再次顯示。若經常有程序自動啟動佔用手機內存,建議:
1.關閉後台運行的程序:點擊屏幕左下角近期任務鍵-點擊要關閉的應用程序右上角的「X」/下方的關閉全部(部分機器操作方式:長按HOME鍵(主屏幕鍵)啟動任務管理器,點擊左下角餅形圖標,點擊清除RAM數據)。
2.部分機器支持智能管理器或內存管理器,建議通過該功能手動關閉自動運行的應用程序。
3.部分第三方軟體支持開機後自動啟動功能,建議打開自動運行的軟體禁用此功能。