JAVA 內存管理

 
1 內存分配策略
  
按照編譯原理的,程序運行內存分配有三策略,是靜,式的,和堆式的.
  
分配是指在編譯時就能確定個數據目在運行刻的存需求,因而在編譯時就可以分配固定的內存.這種分配策略要求程序代中不允 有可數據(比如可)的存在,也不允有嵌套或者遞歸構出,都會編譯程序無法算準確的存需求.
  
式存分配也可稱爲動態分配,是由一個似於堆的運行實現.和靜分配相反,式存方案中,程序數據區的需求在編譯時是完全未知 的,只有到運行的候才能知道,但是定在運行中入一個程序模塊時,知道程序模所需的數據區大小才能夠爲其分配內存.和我在數據構所熟知 的,式存分配按照先後出的原則進行分配。
  
分配要求在編譯時能知道所有量的存要求,式存分配要求在程的入口知道所有的存要求,而堆式存分配則專門負責編譯時或運行入口都無法確定存要求的數據構的內存分配,比如可變長度串和.堆由大片的可利用或空閒塊組,堆中的內存可以按照任意序分配和.
2 堆和的比
 
上面的定編譯原理的教材中總結而來,除靜分配之外,得很呆板和以理解,下面撇分配,集中比堆和:
  
從堆和的功能和作用來通俗的比,堆主要用來存放象的,主要是用來行程序的.這種不同又主要是由於堆和的特點決定的:
  
程中,例如C/C++中,所有的方法調用都是通過棧行的,所有的局部,形式參數都是從中分配內存的。實際上也不是什分配,只是從棧頂 向上用就行,就好像工廠中的(conveyor belt),Stack Pointer會自指引你到放西的位置,你所要做的只是把西放下來就行.退出函數的候,修改就可以把中的內容銷燬.這樣的模式速度最快, 當然要用來運行程序了.需要注意的是,在分配的,比如一個即將要調用的程序模分配數據區,事先知道個數據區的大小,也就然分配是在程 序運行時進行的,但是分配的大小多少是確定的,,"大小多少"是在編譯時確定的,不是在運行.
  
堆是用程序在運行的求操作系分配自己內存,由於從操作系管理的內存分配,所以在分配和銷燬時都要佔用時間,因此用堆的效率非常低.但是堆的 點在於,編譯器不必知道要從堆裏分配多少存,也不必知道存的數據要在堆裏停留多時間,因此,用堆保存數據會得到更大的靈活性。事,面 向象的多,內存分配是必不可少的,態變量所需的存只有在運行時創建了象之後才能確定.C++中,要求建一個,只需用 new命令制相的代即可。些代碼時,會在堆裏自動進行數據的保存.當然,達到這種靈活性,必然會付出一定的代價:在堆裏分配存間時會花 掉更時間也正是致我們剛才所的效率低的原因,看來列寧同志的好,人的點往往也是人的缺點,人的缺點往往也是人的(~).

3 JVM
中的堆和 
  JVM
是基於堆的虛.JVM爲每個新建的程都分配一個堆.也就是,於一個Java程序來,它的運行就是通過對的操作來完成的。堆幀爲單位保存程的狀JVM行兩操作:幀爲單位的壓棧和出操作。
 
知道,某個程正在行的方法稱程的當前方法.可能不知道,當前方法使用的當前。當程激活一個Java方法,JVM就會在程的 Java裏新入一個自然成了當前.在此方法行期,將用來保存參數,局部,間計程和其他數據.裏和編譯 原理中的活動紀錄的概念是差不多的.
 
Java這種分配機制來看,又可以這樣理解:(Stack)是操作系在建立某個或者(在支持多程的操作系中是)爲這程建立的存區域,區域具有先後出的特性。
  
一個Java用都唯一對應一個JVM例,一個例唯一對應一個堆。用程序在運行中所建的所有類實例或數都放在個堆中,並由用所有的程 共享.C/C++不同,Java中分配堆內存是自初始化的。Java中所有象的存都是在堆中分配的,但是象的引用卻是在堆中分配,也 就是在建立一個從兩個地方都分配內存,在堆中分配的內存實際建立象,而在堆中分配的內存只是一個指向個堆象的指(引用)而已。

4 GC
的思考
   Java
?JVM的存在當然是一個原因,但有人,Java,除了簡單類(int,char)的數據,其它都是在堆中分配內存(所以Java的一切都是)也是程序慢的原因之一。
  
我的想法是(應該說代表TIJ),如果沒有Garbage Collector(GC),上面的法就是成立的.堆不象連續的空,沒有法指望堆本身的內存分配能象堆樣擁般的速度,,你整理大的堆空,你幾乎沒有延的從堆中取新的空?
  
,GC站出來解決問題.都知道GC用來清除內存垃圾,出空供程序使用,GC也擔了另外一個重要的任,就是要Java中堆 的內存分配和其他言中堆內存分配一,速度的問題幾乎是衆口一Java.要達到這樣的目的,就必使堆的分配也能做到象,不用自己操心去找空.這樣,GC除了負責清除Garbage,負責整理堆中的,把它們轉移到一個Garbage純淨中無 隔的排列起來,就象堆中一樣緊,這樣Heap Pointer就可以方便的指向的起始位置,或者一個未使用的空,下一個需要分配內存"指引方向".因此可以這樣說,垃圾收集影響了 象的建速度,聽起來很怪,?
  
GC在堆中找到所有存活的象呢?前面,在建立一個,在堆中分配實際建立象的內存,而在堆中分配一個指向個堆象的指(引 用),只要在堆(也有可能在靜)找到個引用,就可以跟蹤到所有存活的.找到之後,GC將它從一個堆的中移到另外一個堆的,並 將它一個挨一個的排列起來,就象我上面的那,出了一個,但又不是先後出的分配,而是可以任意分配的,在速度可以保的情況下, Isnt it great?
  
但是,列寧同志,人的點往往也是人的缺點,人的缺點往往也是人的(~~).GC()的運行要佔用一個,本身就是一個降低程序運行性能 的缺陷,更何況要在堆中把內存翻來覆去的折.如此,如上面所,堆中存活的象被搬移了位置,所有對這象的引用都要重新賦值.開銷都會致性能的降低.
  
此消彼,GC()來的效益是否蓋了它的缺點致的,我也沒有太多的體會,Bruce Eckel Java的支持者,王婆瓜,不能全信.個人的感,Java是很慢,它的需要時間.
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章