自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

本機(jī)內(nèi)存簡介:操作系統(tǒng),硬件限制及虛擬內(nèi)存

開發(fā) 后端
Java 堆耗盡并不是造成 java.lang.OutOfMemoryError 的惟一原因。如果本機(jī)內(nèi)存 耗盡,則會發(fā)生普通調(diào)試技巧無法解決的 OutOfMemoryError。本文將討論本機(jī)內(nèi)存的概念。

本文介紹操作系統(tǒng)和底層硬件給本機(jī)內(nèi)存帶來的限制。

硬件限制

本機(jī)進(jìn)程遇到的許多限制都是由硬件造成的,而與操作系統(tǒng)沒有關(guān)系。每臺計算機(jī)都有一個處理器和一些隨機(jī)存取存儲器(RAM),后者也稱為物理內(nèi)存。處理器將數(shù)據(jù)流解釋為要執(zhí)行的指令,它擁有一個或多個處理單元,用于執(zhí)行整數(shù)和浮點運算以及更高級的計算。處理器具有許多寄存器 —— ??焖俚膬?nèi)存元素,用作被執(zhí)行的計算的工作存儲,寄存器大小決定了一次計算可使用的***數(shù)值。

處理器通過內(nèi)存總線連接到物理內(nèi)存。物理地址(處理器用于索引物理 RAM 的地址)的大小限制了可以尋址的內(nèi)存。例如,一個 16 位物理地址可以尋址 0x0000 到 0xFFFF 的內(nèi)存地址,這個地址范圍包括 2^16 = 65536 個惟一的內(nèi)存位置。如果每個地址引用一個存儲字節(jié),那么一個 16 位物理地址將允許處理器尋址 64KB 內(nèi)存。

處理器被描述為特定數(shù)量的數(shù)據(jù)位。這通常指的是寄存器大小,但是也存在例外,比如 32 位 390 指的是物理地址大小。對于桌面和服務(wù)器平臺,這個數(shù)字為 31、32 或 64;對于嵌入式設(shè)備和微處理器,這個數(shù)字可能小至 4。物理地址大小可以與寄存器帶寬一樣大,也可以比它大或小。如果在適當(dāng)?shù)牟僮飨到y(tǒng)上運行,大部分 64 位處理器可以運行 32 位程序。

表 1 列出了一些流行的 Linux 和 Windows 架構(gòu),以及它們的寄存器和物理地址大小:


表 1. 一些流行處理器架構(gòu)的寄存器和物理地址大小
架構(gòu) 寄存器帶寬(位) 物理地址大?。ㄎ唬?/TH>
(現(xiàn)代)Intel® x86 32 32
36,具有物理地址擴(kuò)展(Pentium Pro 和更高型號)
x86 64 64 目前為 48 位(以后將會增大)
PPC64 64 在 POWER 5 上為 50 位
390 31 位 32 31
390 64 位 64 64

操作系統(tǒng)和虛擬內(nèi)存

如果您編寫無需操作系統(tǒng),直接在處理器上運行的應(yīng)用程序,您可以使用處理器可以尋址的所有內(nèi)存(假設(shè)連接到了足夠的物理 RAM)。但是要使用多任務(wù)和硬件抽象等特性,幾乎所有人都會使用某種類型的操作系統(tǒng)來運行他們的程序。

在 Windows 和 Linux 等多任務(wù)操作系統(tǒng)中,有多個程序在使用系統(tǒng)資源。需要為每個程序分配物理內(nèi)存區(qū)域來在其中運行??梢栽O(shè)計這樣一個操作系統(tǒng):每個程序直接使用物理內(nèi)存,并且可以可靠地僅使用分配給它的內(nèi)存。一些嵌入式操作系統(tǒng)以這種方式工作,但是這在包含多個未經(jīng)過集中測試的應(yīng)用程序的環(huán)境中是不切實際的,因為任何程序都可能破壞其他程序或者操作系統(tǒng)本身的內(nèi)存。

虛擬內(nèi)存 允許多個進(jìn)程共享物理內(nèi)存,而且不會破壞彼此的數(shù)據(jù)。在具有虛擬內(nèi)存的操作系統(tǒng)(比如 Windows、Linux 和許多其他操作系統(tǒng))中,每個程序都擁有自己的虛擬地址空間 —— 一個邏輯地址區(qū)域,其大小由該系統(tǒng)上的地址大小規(guī)定(所以,桌面和服務(wù)器平臺的虛擬地址空間為 31、32 或 64 位)。進(jìn)程的虛擬地址空間中的區(qū)域可被映射到物理內(nèi)存、文件或任何其他可尋址存儲。當(dāng)數(shù)據(jù)未使用時,操作系統(tǒng)可以在物理內(nèi)存與一個交換區(qū)域(Windows 上的頁面文件 或者 Linux 上的交換分區(qū))之間移動它,以實現(xiàn)對物理內(nèi)存的***利用率。當(dāng)一個程序嘗試使用虛擬地址訪問內(nèi)存時,操作系統(tǒng)連同片上硬件會將該虛擬地址映射到物理位置,這個位置可以是物理 RAM、一個文件或頁面文件/交換分區(qū)。如果一個內(nèi)存區(qū)域被移動到交換空間,那么它將在被使用之前加載回物理內(nèi)存中。圖 1 展示了虛擬內(nèi)存如何將進(jìn)程地址空間區(qū)域映射到共享資源:


圖 1. 虛擬內(nèi)存將進(jìn)程地址空間映射到物理資源
虛擬內(nèi)存映射

程序的每個實例以進(jìn)程 的形式運行。在 Linux 和 Windows 上,進(jìn)程是一個由受操作系統(tǒng)控制的資源(比如文件和套接字信息)、一個典型的虛擬地址空間(在某些架構(gòu)上不止一個)和至少一個執(zhí)行線程構(gòu)成的集合。

虛擬地址空間大小可能比處理器的物理地址大小更小。32 位 Intel x86 最初擁有的 32 位物理地址僅允許處理器尋址 4GB 存儲空間。后來,添加了一種稱為物理地址擴(kuò)展(Physical Address Extension,PAE)的特性,將物理地址大小擴(kuò)大到了 36 位,允許安裝或?qū)ぶ分炼?64GB RAM。PAE 允許操作系統(tǒng)將 32 位的 4GB 虛擬地址空間映射到一個較大的物理地址范圍,但是它不允許每個進(jìn)程擁有 64GB 虛擬地址空間。這意味著如果您將大于 4GB 的內(nèi)存放入 32 位 Intel 服務(wù)器中,您將無法將所有內(nèi)存直接映射到一個單一進(jìn)程中。

地址窗口擴(kuò)展(Address Windowing Extension)特性允許 Windows 進(jìn)程將其 32 位地址空間的一部分作為滑動窗口映射到較大的內(nèi)存區(qū)域中。Linux 使用類似的技術(shù)將內(nèi)存區(qū)域映射到虛擬地址空間中。這意味著盡管您無法直接引用大于 4GB 的內(nèi)存,但您仍然可以使用較大的內(nèi)存區(qū)域。

內(nèi)核空間和用戶空間

盡管每個進(jìn)程都有其自己的地址空間,但程序通常無法使用所有這些空間。地址空間被劃分為用戶空間內(nèi)核空間。內(nèi)核是主要的操作系統(tǒng)程序,包含用于連接計算機(jī)硬件、調(diào)度程序以及提供聯(lián)網(wǎng)和虛擬內(nèi)存等服務(wù)的邏輯。

作為計算機(jī)啟動序列的一部分,操作系統(tǒng)內(nèi)核運行并初始化硬件。一旦內(nèi)核配置了硬件及其自己的內(nèi)部狀態(tài),***個用戶空間進(jìn)程就會啟動。如果用戶程序需要來自操作系統(tǒng)的服務(wù),它可以執(zhí)行一種稱為系統(tǒng)調(diào)用 的操作與內(nèi)核程序交互,內(nèi)核程序然后執(zhí)行該請求。系統(tǒng)調(diào)用通常是讀取和寫入文件、聯(lián)網(wǎng)和啟動新進(jìn)程等操作所必需的。

當(dāng)執(zhí)行系統(tǒng)調(diào)用時,內(nèi)核需要訪問其自己的內(nèi)存和調(diào)用進(jìn)程的內(nèi)存。因為正在執(zhí)行當(dāng)前線程的處理器被配置為使用地址空間映射來為當(dāng)前進(jìn)程映射虛擬地址,所以大部分操作系統(tǒng)將每個進(jìn)程地址空間的一部分映射到一個通用的內(nèi)核內(nèi)存區(qū)域。被映射來供內(nèi)核使用的地址空間部分稱為內(nèi)核空間,其余部分稱為用戶空間,可供用戶應(yīng)用程序使用。

內(nèi)核空間和用戶空間之間的平衡關(guān)系因操作系統(tǒng)的不同而不同,甚至在運行于不同硬件架構(gòu)之上的同一操作系統(tǒng)的各個實例間也有所不同。這種平衡通常是可配置的,可進(jìn)行調(diào)整來為用戶應(yīng)用程序或內(nèi)核提供更多空間??s減內(nèi)核區(qū)域可能導(dǎo)致一些問題,比如能夠同時登錄的用戶數(shù)量限制或能夠運行的進(jìn)程數(shù)量限制。更小的用戶空間意味著應(yīng)用程序編程人員只能使用更少的內(nèi)存空間。

默認(rèn)情況下,32 位 Windows 擁有 2GB 用戶空間和 2GB 內(nèi)核空間。在一些 Windows 版本上,通過向啟動配置添加 /3GB 開關(guān)并使用 /LARGEADDRESSAWARE 開關(guān)重新鏈接應(yīng)用程序,可以將這種平衡調(diào)整為 3GB 用戶空間和 1GB 內(nèi)核空間。在 32 位 Linux 上,默認(rèn)設(shè)置為 3GB 用戶空間和 1GB 內(nèi)核空間。一些 Linux 分發(fā)版提供了一個 hugemem 內(nèi)核,支持 4GB 用戶空間。為了實現(xiàn)這種配置,將進(jìn)行系統(tǒng)調(diào)用時使用的地址空間分配給內(nèi)核。通過這種方式增加用戶空間會減慢系統(tǒng)調(diào)用,因為每次進(jìn)行系統(tǒng)調(diào)用時,操作系統(tǒng)必須在地址空間之間復(fù)制數(shù)據(jù)并重置進(jìn)程地址-空間映射。圖 2 展示了 32 位 Windows 的地址-空間布局:


圖 2. 32 位 Windows 的地址-空間布局
Windows 32 位地址空間

圖 3 顯示了 32 位 Linux 的地址-空間配置:


圖 3. 32 位 Linux 的地址-空間布局
Linux 32 位地址空間

31 位 Linux 390 上還使用了一個獨立的內(nèi)核地址空間,其中較小的 2GB 地址空間使對單個地址空間進(jìn)行劃分不太合理,但是,390 架構(gòu)可以同時使用多個地址空間,而且不會降低性能。

進(jìn)程空間必須包含程序需要的所有內(nèi)容,包括程序本身和它使用的共享庫(在 Windows 上為 DDL,在 Linux 上為 .so 文件)。共享庫不僅會占據(jù)空間,使程序無法在其中存儲數(shù)據(jù),它們還會使地址空間碎片化,減少可作為連續(xù)內(nèi)存塊分配的內(nèi)存。這對于在擁有 3GB 用戶空間的 Windows x86 上運行的程序尤為明顯。DLL 在構(gòu)建時設(shè)置了***的加載地址:當(dāng)加載 DLL 時,它被映射到處于特定位置的地址空間,除非該位置已經(jīng)被占用,在這種情況下,它會加載到別處。Windows NT 最初設(shè)計時設(shè)置了 2GB 可用用戶空間,這對于要構(gòu)建來加載接近 2GB 區(qū)域的系統(tǒng)庫很有用 —— 使大部分用戶區(qū)域都可供應(yīng)用程序自由使用。當(dāng)用戶區(qū)域擴(kuò)展到 3GB 時,系統(tǒng)共享庫仍然加載接近 2GB 數(shù)據(jù)(約為用戶空間的一半)。盡管總體用戶空間為 3GB,但是不可能分配 3GB 大的內(nèi)存塊,因為共享庫無法加載這么大的內(nèi)存。

在 Windows 中使用 /3GB 開關(guān),可以將內(nèi)核空間減少一半,也就是最初設(shè)計的大小。在一些情形下,可能耗盡 1GB 內(nèi)核空間,使 I/O 變得緩慢,且無法正常創(chuàng)建新的用戶會話。盡管 /3GB 開關(guān)可能對一些應(yīng)用程序非常有用,但任何使用它的環(huán)境在部署之前都應(yīng)該進(jìn)行徹底的負(fù)載測試。

本機(jī)內(nèi)存泄漏或過度使用本機(jī)內(nèi)存將導(dǎo)致不同的問題,具體取決于您是耗盡了地址空間還是用完了物理內(nèi)存。耗盡地址空間通常只會發(fā)生在 32 位進(jìn)程上,因為*** 4GB 的內(nèi)存很容易分配完。64 位進(jìn)程具有數(shù)百或數(shù)千 GB 的用戶空間,即使您特意消耗空間也很難耗盡這么大的空間。如果您確實耗盡了 Java 進(jìn)程的地址空間,那么 Java 運行時可能會出現(xiàn)一些陌生現(xiàn)象,本文稍后將詳細(xì)討論。當(dāng)在進(jìn)程地址空間比物理內(nèi)存大的系統(tǒng)上運行時,內(nèi)存泄漏或過度使用本機(jī)內(nèi)存會迫使操作系統(tǒng)交換后備存儲器來用作本機(jī)進(jìn)程的虛擬地址空間。訪問經(jīng)過交換的內(nèi)存地址比讀取駐留(在物理內(nèi)存中)的地址慢得多,因為操作系統(tǒng)必須從硬盤驅(qū)動器拉取數(shù)據(jù)??赡軙峙浯罅績?nèi)存來用完所有物理內(nèi)存和所有交換內(nèi)存(頁面空間),在 Linux 上,這將觸發(fā)內(nèi)核內(nèi)存不足(OOM)結(jié)束程序,強(qiáng)制結(jié)束最消耗內(nèi)存的進(jìn)程。在 Windows 上,與地址空間被占滿時一樣,內(nèi)存分配將會失敗。

同時,如果嘗試使用比物理內(nèi)存大的虛擬內(nèi)存,顯然在進(jìn)程由于消耗內(nèi)存太大而被結(jié)束之前就會遇到問題。系統(tǒng)將變得異常緩慢,因為它會將大部分時間用于在內(nèi)存與交換空間之間來回復(fù)制數(shù)據(jù)。當(dāng)發(fā)生這種情況時,計算機(jī)和獨立應(yīng)用程序的性能將變得非常糟糕,從而使用戶意識到出現(xiàn)了問題。當(dāng) JVM 的 Java 堆被交換出來時,垃圾收集器的性能會變得非常差,應(yīng)用程序可能被掛起。如果一臺機(jī)器上同時使用了多個 Java 運行時,那么物理內(nèi)存必須足夠分配給所有 Java 堆。

【編輯推薦】

  1. Java 理論與實踐: 用弱引用堵住內(nèi)存泄漏
  2. Java內(nèi)存泄漏的檢測和處理
  3. 幾種典型的Java內(nèi)存泄漏
  4. 詳細(xì)介紹Java的內(nèi)存管理與內(nèi)存泄露
  5. Java程序性能優(yōu)化之找出內(nèi)存溢出元兇
責(zé)任編輯:yangsai 來源: IBMDW
相關(guān)推薦

2010-06-10 17:12:23

Linux 內(nèi)存監(jiān)控

2010-06-02 11:33:26

Linux 內(nèi)存監(jiān)控

2025-04-30 04:20:00

操作系統(tǒng)虛擬內(nèi)存

2022-08-02 09:02:17

虛擬內(nèi)存操作系統(tǒng)

2009-10-09 09:42:07

虛擬機(jī)內(nèi)存

2019-12-26 08:45:46

Linux虛擬內(nèi)存

2019-04-09 15:56:46

虛擬機(jī)內(nèi)存區(qū)Java

2009-06-17 15:46:36

Java運行時本機(jī)內(nèi)存

2019-03-14 09:29:02

Linux系統(tǒng)內(nèi)存

2023-01-30 00:05:02

操作系統(tǒng)虛擬化安全

2010-05-24 10:32:20

Linux swap

2020-04-14 16:03:31

Linux虛擬內(nèi)存操作系統(tǒng)

2010-04-20 14:17:21

Unix操作系統(tǒng)

2022-11-28 07:21:53

操作系統(tǒng)內(nèi)存管理

2020-03-10 09:30:11

Java內(nèi)存數(shù)據(jù)

2021-05-31 10:03:52

虛擬內(nèi)存管理

2012-09-27 09:41:31

虛擬化

2021-06-01 08:20:55

Linux虛擬內(nèi)存命令

2019-03-20 14:29:46

Linux虛擬內(nèi)存

2010-05-31 16:53:21

Java
點贊
收藏

51CTO技術(shù)棧公眾號