堆棧溢出和內(nèi)存泄漏的區(qū)別?
堆棧溢出
在Java的內(nèi)存結(jié)構(gòu)中,堆棧的大小不是無(wú)限的。大量的方法調(diào)用過(guò)程,導(dǎo)致不斷的堆棧壓入,最終填滿(mǎn)堆棧內(nèi)存,產(chǎn)生StackOv
為什么沒(méi)有編程語(yǔ)言的內(nèi)存管理,是手動(dòng)管理與自動(dòng)垃圾回收相結(jié)合的?
Rust和Objective-C內(nèi)存管理?yè)?jù)bug所知,有兩種語(yǔ)言可以做出這種取舍,一種是Rust,一種是OC。但是它基本上不是主流。
Rust通過(guò)所有權(quán)和生命周期動(dòng)態(tài)管理內(nèi)存,保證運(yùn)行時(shí)100%的內(nèi)存安全,需要手動(dòng)使用時(shí)需要用不安全力標(biāo)記。
Objective-C中有兩種內(nèi)存管理機(jī)制:mrc(MannulReferenceCounting)和arc(AutomaticReferenceCounting),分別提供手動(dòng)和自動(dòng)內(nèi)存管理,以滿(mǎn)足不同的需求。
主流內(nèi)存管理和垃圾收集
每種現(xiàn)代語(yǔ)言都有自己的gc處理方法。盡管每種語(yǔ)言都有自己的策略,但它基本上是基于三種基本方法::引文計(jì)數(shù)、副本收集和標(biāo)記移除。讓讓我們逐一介紹。引用計(jì)數(shù)是一種方便有效的gc管理方法。大多數(shù)現(xiàn)代語(yǔ)言都是基于這種方法,包括但不限于python、php、perl、ruby和js。
引用計(jì)數(shù)的基本原理是程序中的所有對(duì)象(比如變量)都有一個(gè)全局表來(lái)記錄它們被引用的次數(shù)。釋放引用時(shí),計(jì)數(shù)將減少,直到計(jì)數(shù)為零,然后釋放引用。
引用計(jì)數(shù)的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,垃圾可以立即回收。缺點(diǎn)是容易形成循環(huán)引用,永遠(yuǎn)不會(huì)發(fā)布。所以現(xiàn)代語(yǔ)言gc主要是基于引用計(jì)數(shù),然后引入一些改進(jìn)的算法來(lái)解決循環(huán)引用的問(wèn)題。
復(fù)制收藏
該算法將內(nèi)存分為兩塊,其中一塊正常使用。當(dāng)需要gc時(shí),將第一個(gè)塊中仍在使用的對(duì)象復(fù)制到另一個(gè)塊中,然后釋放所有第一個(gè)內(nèi)存塊。該方法避免了對(duì)象存活檢查的遍歷,提高了效率。
Mark-clear這是最早也是應(yīng)用最廣泛的gc方法,也可以說(shuō)gc的一般原理就是這種方法。閱卷有兩個(gè)階段,閱卷階段。段需要標(biāo)記回收的對(duì)象;在恢復(fù)階段,有g(shù)c統(tǒng)一恢復(fù)。
這種方法是有問(wèn)題的,低效的,并且會(huì)產(chǎn)生大量的內(nèi)存碎片。
事實(shí)上,javagc已經(jīng)集成了2,3個(gè)方法,并做了很多其他的改進(jìn)。可以說(shuō)javagc是最先進(jìn)的gc方法。但是由于底層jvm的限制,引用計(jì)數(shù)法無(wú)法使用,所以還是存在一些問(wèn)題。
業(yè)界普遍認(rèn)為,如果將引用計(jì)數(shù)與跟蹤和回收結(jié)合起來(lái),任何GC算法都是最高效和實(shí)用的。