內(nèi)存泄漏的概念磅崭,引用當(dāng)初面試的時(shí)候總結(jié)出來的一句話:當(dāng)對(duì)象使用完需被回收時(shí)藻三,因?yàn)橛写嬖谒囊枚鵁o法被GC回收,就會(huì)出現(xiàn)內(nèi)存泄漏(當(dāng)面試官跟你撕逼內(nèi)存泄漏的時(shí)候就一句話懟死他);
首先我們要知道內(nèi)存是個(gè)什么概念谒麦。我們知道java在jvm虛擬機(jī)中運(yùn)行峻仇,而jvm虛擬機(jī)可劃分為三個(gè)區(qū):棧公黑、堆和方法區(qū)。
jvm記錄了方法的調(diào)用摄咆,每個(gè)線程都會(huì)擁有一個(gè)自己的棧帆调,當(dāng)程序運(yùn)行時(shí),調(diào)用方法豆同,方法入棧番刊,保存了這個(gè)方法的參數(shù)。局部變量和返回的對(duì)象的地址值影锈。在java中芹务,局部變量基本數(shù)據(jù)類型變量或者是對(duì)象的引用蝉绷。所以,對(duì)象的引用只能保存在堆中枣抱。
當(dāng)方法被調(diào)用完畢熔吗,該方法就會(huì)從棧中彈出,所有局部變量和參數(shù)占用的控件被釋放掉佳晶。同理桅狠,當(dāng)所有的棧都被清空的時(shí)候(方法調(diào)用完畢),程序也就運(yùn)行結(jié)束了轿秧。
對(duì)于堆內(nèi)存而言中跌,它里面存放著一些普通變量,而java的機(jī)制是堆內(nèi)存不會(huì)隨著方法的解釋而將內(nèi)存清空菇篡,所以在方法中定義了局部變量的漩符,在方法結(jié)束后依然會(huì)存活在堆中。
所以驱还,我們知道了嗜暴,棧可以自己清理內(nèi)存空間议蟆。而堆不會(huì)闷沥。那么,當(dāng)我們不停地new對(duì)象的時(shí)候咐容,堆的內(nèi)存就會(huì)有被占滿的可能狐赡。所以java引入了GC(垃圾回收器),去處理堆中內(nèi)存的回收疟丙∮敝叮可悲的是,盡管棧被清空了享郊,但是如果對(duì)象的引用一直不被銷毀览祖,就會(huì)占據(jù)著內(nèi)存,這塊內(nèi)存就沒有了它的意義炊琉,不能再使用展蒂,所以就出現(xiàn)了我們文章開頭的那一句:當(dāng)對(duì)象使用完需被回收時(shí),因?yàn)橛写嬖谒囊枚鵁o法被GC回收苔咪,就會(huì)出現(xiàn)內(nèi)存泄漏锰悼。
我們知道,java中的引用類型分為強(qiáng)引用团赏,弱引用箕般,軟引用和虛引用。
而正在造成內(nèi)存泄漏的舔清,正是強(qiáng)引用丝里;
所以曲初,內(nèi)存泄漏的真正原因是:
持有對(duì)象的強(qiáng)引用,無法被GC回收杯聚。
以上就是我所了解到的內(nèi)存泄漏的原因臼婆,希望對(duì)大家有點(diǎn)點(diǎn)幫助。