什麼是內存
計算機組成:控制器,運算器,存儲器,輸入,輸出
存儲器速度: 寄存器 > x級緩存>內存(主存儲器) ==>RAM(Random Access Memory),掉電後數據丟失
硬盤,ROM,flash是輔存儲器,速度遠慢與內存,屬於外設. ==>速度越快,造價越高
移動設備VS電腦: 而PC即使內存不大,系統通過在外存上創建虛擬內存空間實現內存的"增大".android系統底層雖然使用Linux系統,但是默認是沒有啟用swap分區的.因移動設備普遍內存外存都不夠大,都是窮哥們,沒地兒借.
以上:內存是一種稀缺緊張和珍貴的資源,需要珍惜的使用
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的變量)==>看虛擬機的圖
GC算法:
引用計數法(Reference Count)
在每個對象中保存這個對象的引用計數, 引用發生增減時對引用數進行更新, 當引用計數變為0時, 就可以清除了
存在問題:循環引用的對象無法被釋放,多線程存在數據同步的問題
標記-清除算法(mark-sweep)
從根開始把所有被引用的對象用遞歸的方式進行標記,然後回收沒有被標記的對象
存在問題:造成大量的内存碎片,時間與存活對象數和對象總數有關,
複製-收集算法(Copy and Collection)
会将从根开始被引用的对象复制到另外的空间中,然后,再将复制的对象所能够引用的对象用递归的方式不断复制下去。
存在問題:複製對象的開銷比較大,存活比例比較高的情況下很不利,
分代收集算法
不同的對象的生命週期不同,所以可以採用不同的垃圾收集方式. 劃分:年輕代(新創建對象),年老代(n次回收後才活著),持久代(靜態文件等).
GC時會暫停程序的執行
內存洩漏
原因:動態分配的空間使用完沒有釋放
危害:佔據內存空間,可能導致內存溢出
android中常見的5大內存洩漏
1.單例把持context對象
2.資源未關閉造成的洩漏
3.handler造成的內存洩漏
4.線程造成的洩漏
5.非靜態內部類創建靜態實例
找出洩漏:引入LeakCanary,MAT+