天天看點

Atitit vm os記憶體管理 目錄 1. 馮諾依曼結構、哈佛結構、改進型哈佛結構 1 1.1. 馮·諾依曼結構 1 1.2. 哈佛結構 2 1.3. 改進型的哈佛結構與哈佛體系結構差别 3 2.

Atitit vm os記憶體管理

目錄

1. 馮諾依曼結構、哈佛結構、改進型哈佛結構 1

1.1. 馮·諾依曼結構 1

1.2. 哈佛結構 2

1.3. 改進型的哈佛結構與哈佛體系結構差别 3

2. Vm與pc 常用記憶體資料結構 4

2.1. 彙編記憶體布局  資料段  代碼段 堆棧/寄存器 4

2.2. Stack(棧)與Heap(堆) 4

3. Jvm的記憶體布局 4

3.1. Stacks(虛拟機棧) 與棧幀 4

3.1.1. 局部表量表  操作數棧 動态連結  方法傳回位址 4

3.2. Heap(堆區) 5

3.3. Metaspace (元空間) 5

4. Android 運作時 (ART) 和 Dalvik 虛拟機 6

5. Net clr記憶體 6

6. C程式的記憶體布局(Memory Layout) 6

6.1. 靜态區域(全局區域) 6

6.1.1. 文本段(Text) 6

6.1.2. 已初始化讀寫資料段(RW data  -- Initialized Data Segment) 7

6.1.3. 未初始化資料段(BSS --Uninitialized Data Segment) 7

6.2. 動态區域 7

6.2.1. 堆(heap) 7

6.2.2. 棧(stack) 7

7. Ref 8

  1. 馮諾依曼結構、哈佛結構、改進型哈佛結構
    1. 馮·諾依曼結構

馮·諾依曼結構(von Neumann architecture)又稱作普林斯頓體系結構(Princetion architecture)。馮·諾依曼結構的處理器使用同一個存儲器,經由同一個總線傳輸。馮·諾依曼結構處理器具有以下幾個特點:

  • 必須有一個存儲器;
  • 必須有一個控制器;
  • 必須有一個運算器,用于完成算術運算和邏輯運算;
  • 必須有輸入和輸出裝置,用于進行人機通信。
    1. 哈佛結構

哈佛結構是一種将程式指令存儲和資料存儲分開的存儲器結構,如下圖所示。中央處理器首先到程式指令存儲器中讀取程式指令内容,解碼後得到資料位址,再到相應的資料存儲器中讀取資料,并進行下一步的操作(通常是執行)。程式指令存儲和資料存儲分開,可以使指令和資料有不同的資料寬度,如Microchip公司的PIC16晶片的程式指令是14位寬度,而資料是8位寬度。

哈佛結構的微處理器通常具有較高的執行效率。其程式指令和資料指令分開組織和存儲的,執行時可以預先讀取下一條指令。

哈佛結構是指程式和資料空間獨立的體系結構, 目的是為了減輕程式運作時的訪存瓶頸。

哈佛結構能基本上解決取指和取數的沖突問題。

    1. 改進型的哈佛結構與哈佛體系結構差别

與馮.諾曼結構處理器比較,哈佛結構處理器有兩個明顯的特點:

(1).使用兩個獨立的存儲器子產品,分别存儲指令和資料,每個存儲子產品都不允許指令和資料并存;

(2).使用獨立的兩條總線,分别作為CPU與每個存儲器之間的專用通信路徑,而這兩條總線之間毫無關聯。

後來,又提出了改進的哈佛結構,其結構特點為:

(1).使用兩個獨立的存儲器子產品,分别存儲指令和資料,每個存儲子產品都不允許指令和資料并存;

(2).具有一條獨立的位址總線和一條獨立的資料總線,利用公用位址總線通路兩個存儲子產品(程式存儲子產品和資料存儲子產品),公用資料總線則被用來完成程式存儲子產品或資料存儲子產品與CPU之間的資料傳輸;

(3).兩條總線由程式存儲器和資料存儲器分時共用。

現在的處理器,依托CACHE的存在,已經很好的将二者統一起來了。現在的處理器雖然外部總線上看是諾依曼結構的,但是由于内部CACHE的存在,是以實際上内部來看已經類似改進型哈佛結構的了。

  1. Vm與pc 常用記憶體資料結構

常量  靜态變量

局部變量

對象

    1. 彙編記憶體布局  資料段  代碼段 堆棧/寄存器

程序記憶體示意圖.png

    1. Stack(棧)與Heap(堆)

Stack空間(進棧和出棧)由作業系統控制,其主要儲存函數位址、函數參數、局部變量等等,是以Stack空間不需要很大,一般幾MB大小。

  Heap空間由程式員控制,主要包括執行個體域、靜态域、數組元素等,儲存空間比較大,一般為幾百NB到幾GB。正是由于Heap空間由程式員管理,是以容易出現使用不當的問題(如記憶體洩漏),當然,Heap記憶體也是系統GC發生的區域

  1. Jvm的記憶體布局
    1. Stacks(虛拟機棧) 與棧幀
      1. 局部表量表  操作數棧 動态連結  方法傳回位址

  每個棧幀(見上圖)内部都包含一組稱為局部變量表的變量清單。棧幀中局部變量表的長度由編譯期決定,并且存儲于類或接口的二進制表示之中,即通過方法的code屬性儲存及提供給棧幀使用。

操作數棧

  每個棧幀(見上圖)内部都包含一個稱為操作數棧的後進先出( Last-In-First-Out,LIFO)棧。棧幀中操作數棧的最大深度由編譯期決定,并且通過方法的code屬性儲存及提供給棧幀使用。

動态連結  方法傳回位址

  每個棧幀内部都包含一個指向目前方法所在類型的運作時常量池的引用,以便對目前方法的代碼實作動态連結。在class檔案裡面,一個方法若要調用其他方法,或者通路成員變量,則需要通過符号引用(symbolic reference) 來表

方法傳回位址

  方法執行時有兩種退出情況:第一,正常退出,即正常執行到任何方法的傳回位元組碼指令,如RETURN、IRETURN、ARETURN等;第二,異常退出。無論何種退出情況,都将傳回至方法目前被調用的位置。方法退出的過程相當于彈出目前棧幀,退出可能有三種方式:

傳回值壓入上層調用棧幀。

異常資訊抛給能夠處理的棧幀。

PC計數器指向方法調用後的下一條指令。

    1. Heap(堆區)

  Heap是OOM故障最主要的發源地,它存儲着幾乎所有的執行個體對象,堆由垃圾收集器自動回收,堆區由各子線程共享使用。通

    1. Metaspace (元空間)

  早在JDK8版本中,元空間的前身Perm區(永久代)已經被淘汰。在JDK7及之前的版本中,隻有Hotspot才有Perm區,譯為永久代,它在啟動時固定大小,很難進行調優,并且FGC時會移動類元資訊。在某些場景下,如果動态加載類過多,容易産生Perm區的0OM。比如某個實際Web工程中,因為功能點比較多,在運作過程中,

摘抄整理自《深入了解jav

  1. Android 運作時 (ART) 和 Dalvik 虛拟機
  2. Net clr記憶體

C++記憶體包括:棧,堆,全局/靜态存儲區,常量區,程式代碼區。

C#記憶體包括:棧,堆,全局/靜态存儲區,常量區,自由存儲區。

CLR:棧、GC堆、大對象堆。

,C#之記憶體配置設定

在C#中,記憶體分成5個區,他們分别是堆、棧、自由存儲區、全局/靜态存儲區和常量存儲區。

棧,就是那些由編譯器在需要的時候配置設定,在不需要的時候自動清楚的變量的存儲區。裡面的變量通常是局部變量、函數參數等。

堆,就是那些由new配置設定的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。如果程式員沒有釋放掉,那麼在程式結束後,作業系統會自動回收。

自由存儲區,就是那些由malloc等配置設定的記憶體塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。

全局/靜态存儲區,全局變量和靜态變量被配置設定到同一塊記憶體中。

常量存儲區,這是一塊比較特殊的存儲區,他們裡面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多)

  1. C程式的記憶體布局(Memory Layout)
    1. 靜态區域(全局區域)

全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域(RW data),未初始化的全局變量和未初始化的靜态變量在相鄰的另一塊區域(BSS)。 程式結束後有系統釋放

      1. 文本段(Text)

   通常代碼段和隻讀資料段合成為文本段(Text), 包含實際要執行的代碼(機器指令)和常量。它通常是共享的,多個執行個體之間共享文本段。文本段是不可修改的。

        1. 代碼段(Code)

        代碼段由程式中執行的機器代碼組成。在C語言中,程式語句進行編譯後,形成機器代碼。在執行程式的過程中,CPU的程式計數器指向代碼段的每一條機器代碼,并由處理器依次運作。

        1. 隻讀資料段(RO data,即常量區)

        隻讀資料段是程式使用的一些不會被更改的資料,使用這些資料的方式類似查表式的操作,由于這些變量不需要更改,是以隻需要放置在隻讀存儲器中即可。

       通常字元串常量就是放置在這裡,程式結束後由系統釋放。

        注意:這個區域的存在與否,一直是一個争議的地方,但是我們這裡認同是存在的,因為我們的程式中的确出現了與其他資料段不同的一塊區域,但是往往很多時候大家把隻讀資料段(RO data)和下面的已初始化讀寫資料段(RW data)合成為資料段data,但是其實這個是不合适的,因為在執行過程中,這兩個區域的讀寫權限是不同的,顧名思義,隻讀資料段(RO data)是隻讀的,而已初始化讀寫資料段是可讀可寫的。

      1. 已初始化讀寫資料段(RW data  -- Initialized Data Segment)

        已初始化資料是在程式中聲明,并且具有初值的變量,這些變量需要占用存儲器的空間,在程式執行時它們需要位于可讀寫的記憶體區域内,并具有初值,以供程式運作時讀寫。

      1. 未初始化資料段(BSS --Uninitialized Data Segment)

        未初始化資料是在程式中聲明,但是沒有初始化的變量,這些變量在程式運作之前不需要占用存儲器的空間。

    1. 動态區域
      1. 堆(heap)

       堆記憶體隻在程式運作時出現,一般由程式員配置設定和釋放。在具有作業系統的情況下,如果程式沒有釋放,作業系統可能在程式(例如一個程序)結束後回收記憶體。注意它與資料結構中的堆是兩回事,配置設定方式倒是類似于連結清單。

      1. 棧(stack)

        棧記憶體隻在程式運作時出現,在函數内部使用的變量、函數的參數以及傳回值将使用棧空間,棧空間由編譯器自動配置設定和釋放。其操作方式類似于資料結構中的棧。

  代碼段(Code)、隻讀資料段(RO data)、讀寫資料段(RW Data)、未初始化資料段(BSS)屬于靜态區域。

  堆和棧屬于動态區域。

代碼段(Text)、隻讀資料段(RO data)和初始化讀寫資料段(RW data)在程式連結後即産生,存在與可執行檔案中

  1. Ref

C程式的記憶體布局(Memory Layout)-阿裡雲開發者社群

JVM之記憶體布局超詳細整理 - 簡書

Android記憶體管理分析總結 - 簡書

(···條消息)C# 記憶體配置設定,CLR記憶體配置設定,.NET架構_寫給自己看的部落格-CSDN部落格_c# 記憶體配置設定