Android內存優化

什麼是內存

計算機組成:控制器,運算器,存儲器,輸入,輸出

Android內存優化_第1张图片
計算組成

存儲器速度: 寄存器 > x級緩存>內存(主存儲器) ==>RAM(Random Access Memory),掉電後數據丟失

硬盤,ROM,flash是輔存儲器,速度遠慢與內存,屬於外設. ==>速度越快,造價越高

移動設備VS電腦: 而PC即使內存不大,系統通過在外存上創建虛擬內存空間實現內存的"增大".android系統底層雖然使用Linux系統,但是默認是沒有啟用swap分區的.因移動設備普遍內存外存都不夠大,都是窮哥們,沒地兒借.

以上:內存是一種稀缺緊張和珍貴的資源,需要珍惜的使用


Java虛擬機運行時的數據區

Android內存優化_第2张图片
Java虚拟机运行时数据区

<盡請期待>


內存優化:省著用

一些內存的開支情況

任何一个Java类,包括内部类、匿名类,都要占用大概500字节的内存空间

使用枚举通常会比使用静态常量要消耗两倍以上的内存

任何一个类的实例至少消耗16字节的内存开支

在使用HashMap时,即使你只设置了一个基本数据类型的键,比如说int,但是也会按照对象的大小来分配内存,大概是32字节,而不是4字节

ArrayList中定義的MIN_CAPACITY_INCREMENT=12, LinkedList每個節點會儲存previous和next節點地址

StringBuider中定義INITIAL_CAPACITY=16, 擴大的算法 int newCount = ((value.length>>1) +value.length) +2

因此,少用枚舉,少創建對象,謹慎選擇和使用集合

使用優化後的數據類型(SparseArray,SparseBooleanArray,SparseIntArray,LongSparseArray)

變量的作用域

局部變量和成員變量

圖片加載

加載到內存的圖片大小不是電腦上看到的大小,而是按照像素計算:

一張1500*1000分辨率照片,使用的ARGB_8888颜色类型,每個像素點佔用4字節內存,總內存就是1500*1000*4字節,總內存就是5.7M

排序算法

<盡請期待>


內存優化:及時釋放

內存是如何釋放的:GC(Garbage Collection)

辣雞(Garbage):待釋放的對象

根(Root):一般指堆內存之外,程序能直接访问到的对象(靜態/全局變量,Thread-Local的變量)==>看虛擬機的圖

Android內存優化_第3张图片

GC算法:

引用計數法(Reference Count)

在每個對象中保存這個對象的引用計數, 引用發生增減時對引用數進行更新, 當引用計數變為0時, 就可以清除了

存在問題:循環引用的對象無法被釋放,多線程存在數據同步的問題

標記-清除算法(mark-sweep)

從根開始把所有被引用的對象用遞歸的方式進行標記,然後回收沒有被標記的對象

存在問題:造成大量的内存碎片,時間與存活對象數和對象總數有關,

Android內存優化_第4张图片

複製-收集算法(Copy and Collection)

会将从根开始被引用的对象复制到另外的空间中,然后,再将复制的对象所能够引用的对象用递归的方式不断复制下去。

存在問題:複製對象的開銷比較大,存活比例比較高的情況下很不利,

分代收集算法

不同的對象的生命週期不同,所以可以採用不同的垃圾收集方式. 劃分:年輕代(新創建對象),年老代(n次回收後才活著),持久代(靜態文件等).

Android內存優化_第5张图片
分代收集算法

GC時會暫停程序的執行


內存洩漏

原因:動態分配的空間使用完沒有釋放

危害:佔據內存空間,可能導致內存溢出

android中常見的5大內存洩漏

1.單例把持context對象

2.資源未關閉造成的洩漏

3.handler造成的內存洩漏

4.線程造成的洩漏

5.非靜態內部類創建靜態實例

找出洩漏:引入LeakCanary,MAT+

你可能感兴趣的:(Android內存優化)