java 基本功 —— 内存相关
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
首先我們來說說內(nèi)存,因?yàn)閺膬?nèi)存的角度來出發(fā)來分析一些變量,引用或者對(duì)象的生命周期會(huì)更好理解一些。
java是一門編程語言,他跟C++有什么不同呢?本質(zhì)上,他們都是一樣的,殊途同歸。因?yàn)榈讓佣际遣僮鲀?nèi)存和磁盤的工具,只是語法不同,表現(xiàn)形式不同而已。
所以有的時(shí)候不必刨根問底,因?yàn)檫@可能只是語言的一種規(guī)則而已。
java中都是以對(duì)象和對(duì)象的引用形式來操作數(shù)據(jù)的,那么java中是如何分配這些存儲(chǔ)引用和內(nèi)存的呢?
?
一、 java 中的內(nèi)存塊
1. 寄存器。這是最快的存儲(chǔ)區(qū),以為它位于不同于其他存儲(chǔ)區(qū)的地方——處理器內(nèi)部。但是寄存器的數(shù)量極其有限,所以寄存器根據(jù)需求進(jìn)行分配。你不能直接控制,也不能在程序中感覺到寄存器存在的任何跡象。
2. 棧(又名堆棧),原型就是碟盤子模型,先放的盤子后拿。棧位于通用RAM(隨機(jī)訪問存儲(chǔ)器)中,但通過堆棧指針可以直接從處理器那里獲得直接支持。通過棧頂指針的上下移動(dòng)來創(chuàng)建和釋放內(nèi)存,這是一種快速有效的分配存儲(chǔ)的方法,僅次于寄存器。但是這種方式,java系統(tǒng)必須知道存儲(chǔ)在堆棧內(nèi)所有項(xiàng)的生命周期,以便上下移動(dòng)堆棧指針。所以對(duì)象的引用存在與堆棧中(因?yàn)橛纱_切的生命周期),但是對(duì)象不會(huì)存于堆棧中(無確切的生命周期)。
3.堆。一種通用的內(nèi)存池,也是位于RAM區(qū),用于存放所有的java對(duì)象。堆不同與堆棧的好處是:編譯器不需要知道存儲(chǔ)的數(shù)據(jù)在堆里存活多長時(shí)間。因此,在堆里分配存儲(chǔ)由很大的靈活性。當(dāng)需要一個(gè)對(duì)象時(shí),只需new一個(gè),當(dāng)執(zhí)行時(shí),會(huì)自動(dòng)在堆里進(jìn)行分配內(nèi)存。當(dāng)然,為了這種靈活性必須付出相應(yīng)的代價(jià):用堆進(jìn)行存儲(chǔ)分配和清理可能比用堆棧進(jìn)行存儲(chǔ)分配需要更多的時(shí)間。(對(duì)比于C++,對(duì)象會(huì)在棧中存儲(chǔ),因?yàn)閷?duì)象的生命周期都是程序員自己控制的)
4.常量存儲(chǔ)。常量值通常直接存放在程序代碼的內(nèi)部。
5.非RAM存儲(chǔ)。如果數(shù)據(jù)完全存活于程序之外,那么可以不受程序的任何控制,在程序沒有運(yùn)行時(shí)也可以存在。其中兩個(gè)基本的例子就是流對(duì)象和持久化對(duì)象。在流對(duì)象中,對(duì)象轉(zhuǎn)化成字節(jié)流,通常被發(fā)送給另一臺(tái)機(jī)器。在持久化對(duì)象中,對(duì)象被存放于磁盤上,因此,即使程序終止,他們?nèi)钥梢员3肿约旱臓顟B(tài)。這種存儲(chǔ)方式的技巧在于:把對(duì)象轉(zhuǎn)化成為可以存儲(chǔ)在其他媒介上的事物,在需要時(shí),可恢復(fù)成常規(guī)的、基于RAM的對(duì)象。java提供了對(duì)輕量級(jí)持久化的支持。
二、基本類型在棧中
java對(duì)于小的,基本的變量是這樣處理的:
將他們固定長度,直接存儲(chǔ)值于堆棧中,所以java的基本類型都是有固定取值范圍的。
java基本類型長度不變也是java的可移植性的重要原因。
三、對(duì)象的生命周期
變量的生命周期往往是由大括號(hào)決定的,而對(duì)象則不然
{
??? String s = new String("a? string");
}
在上面的這段代碼中,引用s在作用域終點(diǎn)就消失了。然而,s指向的String對(duì)象仍然繼續(xù)占據(jù)著內(nèi)存空間。
我們已經(jīng)無法在作用與之外訪問這個(gè)對(duì)象,因?yàn)樗ㄒ坏囊靡呀?jīng)失效了。
事實(shí)證明,由new創(chuàng)建的對(duì)象,只要你需要,就會(huì)一直保留下去。
那么他們什么時(shí)候消亡,以至于不會(huì)填滿內(nèi)存呢?這就引出了垃圾回收器。
垃圾回收器的作用:監(jiān)視new創(chuàng)建的所有對(duì)象,并辨識(shí)哪些對(duì)象是不會(huì)再被引用的對(duì)象,隨后,釋放這些對(duì)象的內(nèi)存空間,以便供其他新的對(duì)象使用。所以對(duì)象不需要程序員自己回收。神奇的GC...
三、有關(guān)static
class StaticTest {
??? static int i = 47;
}
即使你創(chuàng)建了兩個(gè)StaticTest對(duì)象,StaticTest.i也只有一份存儲(chǔ)空間,這兩個(gè)對(duì)象共享一個(gè)i。
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
在這里,st1.i和 st2.i指向同一存儲(chǔ)空間,因此他們具有相同的值47.
所以static字段對(duì)每個(gè)類來說只有一份存儲(chǔ)空間,而非static字段則是對(duì)每個(gè)對(duì)象有一個(gè)存儲(chǔ)空間。
?
轉(zhuǎn)載于:https://my.oschina.net/u/2561483/blog/707913
總結(jié)
以上是生活随笔為你收集整理的java 基本功 —— 内存相关的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线编写php文件,php单文件版在线代
- 下一篇: day20 django