不是所有指令都執(zhí)行得又快又好,下面介紹內(nèi)存及它如何影響系統(tǒng)運行。普遍認為,多數(shù)程序語言接近硬件或高性能,如C、C++和Fortran,通常程序員會自己管理內(nèi)存,高手工程師對內(nèi)存的分配,會慎重處理,并在未來結(jié)束使用時再次分配,一旦確認何時及怎樣分配內(nèi)存,內(nèi)存管理的品質(zhì)就依賴于工程師的技能跟效率。實際情況是工程師們,不都會去追蹤那零碎的內(nèi)存碎片。程序開發(fā)是個混亂又瘋狂的過程,內(nèi)存通常都沒辦法完全被釋放,這些被囚禁的內(nèi)存叫內(nèi)存泄露。
概述
內(nèi)存空間使用完畢但因被其他對象引用而未被回收就是內(nèi)存泄漏。
內(nèi)存分配策略
- 靜態(tài)區(qū):
內(nèi)存在程序編譯的時候就已經(jīng)分配好,該內(nèi)存中數(shù)據(jù)的生命周期是貫穿整個程序的。
該存儲區(qū)主要存放靜態(tài)數(shù)據(jù)、全局的static數(shù)據(jù)和一些常量。 - 棧區(qū):
參數(shù)、局部變量等值一般存儲于該區(qū),在方法執(zhí)行完之后釋放。
棧內(nèi)存內(nèi)置在處理器中,分配的運算速度很快,但容量有限。 - 堆區(qū):
也叫動態(tài)內(nèi)存分配區(qū)。可以通過new(malloc - C語言)的方式申請分配一個內(nèi)存。在C/C++中需要手動釋放,Java中則通過CG釋放。在Java中,所有對象都是保存在堆內(nèi)存中。
區(qū)別
堆是不連續(xù)的內(nèi)存區(qū)域,分配靈活,空間也比較大。
棧是連續(xù)的內(nèi)存區(qū)域,大小由操作系統(tǒng)決定。因為堆內(nèi)存不是連續(xù)的內(nèi)存區(qū)域,且動態(tài)分配,因此頻繁的new/remove會造成大量的內(nèi)存碎片,這樣就會慢慢導致效率低下。
對于棧內(nèi)存,先進先出,進出完全不會產(chǎn)生碎片,運行效率高且穩(wěn)定。
舉例
成員變量存儲與堆中(包括基本數(shù)據(jù)類型、引用及引用的對象實體)- 因為他們屬于類,類對象最終是要被new出來的。
局部變量的基本數(shù)據(jù)類型和引用存儲于棧當中 - 因為他們屬于方法中的變量,生命周期會隨著方法一起結(jié)束。
對于棧內(nèi)存和靜態(tài)內(nèi)存,是不會出現(xiàn)內(nèi)存泄漏的。
內(nèi)存管理方式
算法
LRUCache:最近最少使用先回收
特殊Java類
- StrongReference:強引用?;厥諜C制:從不回收。使用:對象一般保存。生命周期:JVM停止時才會終止。
- SoftReference:軟引用?;厥諜C制:內(nèi)存不足時回收。使用:SoftReference結(jié)合ReferenceQueue構造。生命周期:內(nèi)存不足時終止。
- WeakReference:弱引用?;厥諜C制:垃圾回收時回收。使用:WeakReference結(jié)合ReferenceQueue構造。生命周期:GC時終止。
- PhatomReference:虛引用?;厥諜C制:垃圾回收時回收。使用:結(jié)合ReferenceQueue跟蹤垃圾回收。生命周期:GC時終止。