內存泄漏的概念,引用當初面試的時候總結出來的一句話:當對象使用完需被回收時,因為有存在它的引用而無法被GC回收,就會出現(xiàn)內存泄漏(當面試官跟你撕逼內存泄漏的時候就一句話懟死他);
首先我們要知道內存是個什么概念。我們知道java在jvm虛擬機中運行,而jvm虛擬機可劃分為三個區(qū):棧、堆和方法區(qū)。
jvm記錄了方法的調用,每個線程都會擁有一個自己的棧,當程序運行時,調用方法,方法入棧,保存了這個方法的參數(shù)。局部變量和返回的對象的地址值。在java中,局部變量基本數(shù)據(jù)類型變量或者是對象的引用。所以,對象的引用只能保存在堆中。
當方法被調用完畢,該方法就會從棧中彈出,所有局部變量和參數(shù)占用的控件被釋放掉。同理,當所有的棧都被清空的時候(方法調用完畢),程序也就運行結束了。
對于堆內存而言,它里面存放著一些普通變量,而java的機制是堆內存不會隨著方法的解釋而將內存清空,所以在方法中定義了局部變量的,在方法結束后依然會存活在堆中。
所以,我們知道了,棧可以自己清理內存空間。而堆不會。那么,當我們不停地new對象的時候,堆的內存就會有被占滿的可能。所以java引入了GC(垃圾回收器),去處理堆中內存的回收。可悲的是,盡管棧被清空了,但是如果對象的引用一直不被銷毀,就會占據(jù)著內存,這塊內存就沒有了它的意義,不能再使用,所以就出現(xiàn)了我們文章開頭的那一句:當對象使用完需被回收時,因為有存在它的引用而無法被GC回收,就會出現(xiàn)內存泄漏。
我們知道,java中的引用類型分為強引用,弱引用,軟引用和虛引用。
而正在造成內存泄漏的,正是強引用;
所以,內存泄漏的真正原因是:
持有對象的強引用,無法被GC回收。
以上就是我所了解到的內存泄漏的原因,希望對大家有點點幫助。