Bộ nhớ ảo

Trong tin học, bộ nhớ ảo là một kĩ thuật quản lý bộ nhớ được thực hiện bởi phần mềm và phần cứng. Nó sẽ liên kết địa chỉ ô nhớ được dùng bởi phần mềm, gọi là địa chỉ ảo, tới địa chỉ vật lý trong bộ nhớ máy tính. Bộ nhớ chính được các tác vụ coi như là những khoảng trống có địa chỉ liên tiếp hoặc tập hợp những vùng liên tiếp. Hệ điều hành quản lý các ô địa chỉ ảo và sự phân vùng từ ổ nhớ thực đến ổ nhớ ảo. Phần cứng phụ trách xử lý địa chỉ nằm trong CPU, thường được gọi tên là MMU (đơn vị quản lý bộ nhớ), sẽ tự động chuyển địa chỉ ảo sang địa chỉ vật lý. Phần mềm nằm trong hệ điều hành có thể tạo ra những vùng địa chỉ ảo nằm mở rộng khả năng lưu trữ vật lý của bộ nhớ và từ đó chương trình sẽ có nhiều bộ nhớ hơn thực tế máy tính có. 
Lợi ích quan trọng nhất của bộ nhớ ảo là đảm nhiệm giùm các ứng dụng quản lý vùng bộ nhớ được chia sẻ, tăng độ an toàn cho các vùng nhớ và giúp chương trình sử dụng nhiều bộ nhớ nhiều hơn bộ nhớ vật lý mà phần cứng máy tính có, dựa trên kĩ thuật phân trang

Đặc điểm

Bộ nhớ ảo khiến cho việc lập trình ứng dụng dễ dàng hơn bởi chúng làm ẩn đi sự phân mảnh bộ nhớ vật lý, bằng cách ủy thác cho kernel hệ điều hành sự quản lý phân cấp bộ nhớ (loại bỏ việc chương trình máy tính tự xử lý việc sử dụng chồng ô nhớ). Mỗi khi ứng dụng sử dụng không gian bộ nhớ được chỉ định bởi ứng dụng, bộ nhớ ảo sẽ ngăn ngừa việc phân bố lại ô nhớ hoặc cho truy cập ô nhớ có địa chỉ ảo tương ứng.
Sự ảo hóa bộ nhớ có thể được xem như là sự tổng hợp hóa của khái niệm bộ nhớ ảo

Sử dụng

Bộ nhớ ảo là một phần không thể thiếu của một kiến trúc máy tính hiện đại,việc sử dụng cần sử hỗ trợ của phần cứng, thông thường dưới hình thức của đơn vị quản lý bộ nhớ được tích hợp trong CPU.Mặc dù không cần thiết,nhưng giả lập hoặc các máy ảo có thể được sử dụng để hỗ trợ  việc triển khai sử dụng bộ nhớ ảo.Do đó, những hệ điều hành cũ, như những hệ thống những năm 1960,và những máy tính (PC) của đầu cho tới giữa những năm 1980s sẽ không  có chức năng bộ nhớ ảo, những ngoại lệ bao gồm:
. Atlas supervisor cho Atlas
. MCP cho Burrrough B5000
. Multics cho GE 645
. Hệ điều hành Time Sharing cho RCA Model 67
. hệ điều hành cho Apple Lisa là 1 ví dụ cho hệ điều hành PC của những năm 80 mà có bộ nhớ ảo.
Trong những năm 1960 tới 70, bộ nhớ máy tính rất đắt.Sự xuất hiện của bộ nhớ ảo tạo điều kiện cho những chương trình với yêu cầu bộ nhớ lớn để chạy trên những máy tính có bộ nhớ thực nhỏ hơn. Những chi phí tiết kiệm được đã tạo được động lực để tất cả hệ điều hành sử dụng bộ nhớ ảo.Khả năng sử dụng bộ nhớ ảo của máy tính đã tạo thêm 1 mức độ bảo mật và đáng tin cậy, dẫn đến việc bộ nhớ ảo ngày càng “ hot “ trên thị trường.
Hầu hết những hệ điều hành hiện đại  có hỗ trợ bộ nhớ ảo đều chạy hoặc thực hiện những xử lý của mình ở 1 không gian địa chỉ riêng biệt của mình. Vì đó mà từng chương trình có khả năng truy cập bộ nhớ ảo riêng. Tuy nhiên,có những hệ điều hành cũ (như OS/VS1 và OS/VS2 SVS) và những ví dụ hiện đại hơn (như IBM) là hệ điều hành không gian địa chỉ duy nhất mà trong đó tất cả các quá trình xử lý được thực hiện  trong 1 không gian địa chỉ duy nhất,
Hệ thống nhúng và những hệ thống có chức năng đặc biệt yêu cầu thời gian xử lý rất nhanh thường chọn không sử dụng bộ nhớ ảo, hệ thống có bộ nhớ ảo thường gây ra những lỗi không mong muốn trong quá tình chạy I/O. Điều này xảy ra vì hệ thống nhúng thường giảm thiểu chi phí phần cứng bằng cách chạy các tác vụ trên bằng chương trình(1 kĩ thuật gọi là bit-banging) thay vì phần cứng.

Lịch sử

Vào những năm thập niên bốn mươi, năm mươi thế kỉ 20, tất cả những phần mềm lớn cần phải có những Logic trong việc quản lý các thiết bị lưu trữ cấp 1 và 2, như là phương pháp Overlaying. Bộ nhớ ảo đã được giới thiệu không những làm mở rộng bộ nhớ cấp 1, mà còn giúp các lập trình viên dễ dàng trong việc sử dụng. Để chấp nhận cho việc chạy đa chương (multiprogramming) và đa nhiệm (multitasking), nhiều hệ thống đầu tiên đã chia bộ nhớ chạy nhiều chương trình mà không cần bộ nhớ ảo, ví dụ như  PDP-10 via registers
Bản mẫu đầu tiên của bộ nhớ ảo được lần đầu tiên phát triển bởi nhà vật lý người Đức Fritz-Rudolf Güntsch tại Technische Universität Berlin vào năm 1956 trong bài luận án tiến sĩ của ông, Logical Design of a Digital Computer with Multiple Asynchronous Rotating Drums and Automatic High Speed Memory Operation; mô tả về một cỗ máy với 6 “100 khối” lõi bộ nhớ và một vùng địa chỉ với 1000 “100 khối”, với phần cứng tự động dịch chuyển các khối giữa bộ nhớ cấp 1 và bộ nhớ drum cấp 2. Paging đã được thiết lập tại Đại học Manchester như là một cách để mở rộng bộ nhớ làm việc của máy tính Atlas bằng cách hợp 16 ngàn lõi bộ nhớ cấp 1 với 96 ngàn bộ nhớ drum cấp 2. Máy tính Atlas được sử dụng đầu tiên vào năm 1962 nhưng nó đã được chạy những nguyên bản của paging vào năm 1959. Vào năm 1961, Tổng công ty Burroughs đã độc lập tuyên bố phiên bản máy tính thương mại đầu tiên với bộ nhớ ảo, B5000, với những segments (hơn paging).
Trước khi bộ nhớ ảo được tạo trong hệ điều hành chính, đã xuất hiện nhiều lỗi về địa chỉ bộ nhớ. Bộ dịch địa chỉ động (Dynamic Address Translation) có giá rất mắc và rất khó để thiết lập phần cứng, những lần làm việc đầu tiên đã làm chậm tốc độ truy cập bộ nhớ từ từ. Đã có những lo lắng về hệ thống mới với những thuật toán mở để sử dụng lưu trữ cấp 2 sẽ không hiệu quả hơn những thuật toán trước đó. Vào năm 1969, những cuộc tranh luận về bộ nhớ ảo phiên bản thương mại chấm dứt, một đội nghiên cứu IBM của David Sayre đã chỉ ra rằng hệ thống bộ nhớ ảo của họ hoạt động ổn định tốt hơn những hệ thống điều khiển bằng tay khác. Phiên bản máy tính mini đầu tiên đã sử dụng bộ nhớ ảo mới với tên là Norwegian NORD-1. Trong suốt những năm 70 thế kỉ 20, nhiều máy tính mini khác cũng giới thiệu bộ nhớ ảo, đáng chú ý nhất là đời VAX chạy dưới nền VMS.
Bộ nhớ ảo được công bố với kiến trúc x86 dưới chế độ bảo vệ của Bộ vi xử lý Intel 80286. Intel 80386 đã giới thiệu công nghệ paging dưới nhiều lớp, mở khả năng hoạt động các trang lỗi. Tuy nhiên, việc tải những ký tự rất tốn kém, từ đó những nhà thiết kế Hệ Điều Hành hoàn toàn tin tưởng trong việc sử dụng paging tốt hơn một sự kết hợp giữa Paging và Segmentation.

Bảng trang

"Bảng trang" được dùng để biên dịch địa chỉ ảo, là địa chỉ mà những ứng dụng thấy được, sang địa chỉ thực, địa chỉ mà phần cứng sử dụng để thực thi lệnh; thiết bị phần cứng điều khiển quá trình biên dịch đặc biệt này được gọi là “đơn vị quản lý vùng nhớ” (Memory Management Unit - MMU). Mỗi cổng vào của "trang bảng" có một “lá cờ” cho biết “trang” đang được xét có nằm trong vùng nhớ thật (không ảo) hay không. Nếu đang nằm trong vùng nhớ thật, cổng vào của "trang bảng" sẽ chứa địa chỉ của vùng nhớ thật đó nơi mà trang đó được lưu. Khi mối quan hệ giữa một “trang” và thiết bị phần cứng được tạo nên, nếu cổng vào tương ứng trên "trang bảng" biểu thị rằng “trang” đó không nằm trong một vùng nhớ thật, thiết bị phần cứng sẽ gây ra một hiện tượng gọi là “loại bỏ trang lỗi”, tạo nên thành phần “giám sát trang” của hệ điều hành.
Hệ thống có thể có một "trang bảng" cho cả hệ thống, hoặc nhiều "trang bảng" riêng biệt cho mỗi ứng dụng và phân vùng, hoặc một cây "trang bảng" cho những phân vùng lớn hơn hoặc là những sự kết hợp giữa những loại trên. Trong trường hợp chỉ có một "trang bảng", nhiều chương trình cùng chạy đồng thời sẽ sử dụng những phần khác nhau trong độ dài của địa chỉ ảo. Nếu có nhiều "trang bảng" hoặc trang vùng, sẽ tồn tại nhiều địa chỉ ảo và nhiều chương trình chạy đồng thời với những "trang bảng" chuyển hướng tới những địa chỉ thật khác nhau.

Giám sát trang

Đây là thành phần của hệ điều hành tạo ra và quản lý những "trang bảng". Nếu hiện tượng “loại bỏ trang lỗi” xuất hiện từ phần cứng, hệ thống giám sát trang sẽ truy cập vào ổ lưu trữ phụ, trả về một trang có lưu địa chỉ ảo nơi trang lỗi xuất hiện, sau đó sẽ cập nhật "trang bảng" để phản chiếu vị trí vật lý của bộ nhớ ảo và báo bộ biên dịch thực hiện lại yêu lại.
Khi mà mọi vùng nhớ vật lý được sử dụng, “giám sát trang” bắt buộc phải giải phóng một trang trong bộ nhớ chính để lưu giữ một trang thay thế. Bộ giám sát sử dụng một trong những thuật toán thay thế trang như “ít sử dụng nhất” để quyết định trang bị loại bỏ.

Trang ghim

Hệ điều hành có các khu vực bộ nhớ được ghim (không bao giờ trao đổi để lưu trữ thứ cấp). Các thuật ngữ khác được dùng như trang khóa, trang cố định, hoặc trang kết nối. Ví dụ, cơ chế ngắt dựa trên một mảng của các con trỏ chỉ đến lệnh xử lý, chẳng hạn như I/O hoàn thành và lỗi trang. Nếu các trang có chứa các con trỏ hoặc các mã mà họ gọi là trang, "gián đoạn - xử lý" sẽ trở nên phức tạp hơn và tốn thời gian, đặc biệt là trong trường hợp bị gián đoạn do lỗi trang. Do đó, một số phần của cấu trúc "bảng trang" là không có trang.
Một số trang có thể được gắn trong một thời gian ngắn, những trang khác có thể được gắn trong một thời gian dài, và những trang còn lại có thể được gắn vĩnh viễn. Ví dụ:
Mã giám sát trang và trình điều khiển cho các thiết bị lưu trữ thứ cấp trong các trang phải được gắn vĩnh viễn, nếu không phân trang thậm chí sẽ không làm việc vì không có các mã cần thiết.
Các thành phần theo thời gian có thể được gắn để tránh sự chậm trễ của các biến trang.
Bộ đệm dữ liệu được truy cập trực tiếp bởi các thiết bị ngoại vi mà sử dụng truy cập bộ nhớ trực tiếp hoặc kênh I/O phải nằm trong các trang ghim khi các lệnh vận hành I/O đang được tiến hành. Bởi vì các thiết bị ấy và những “xe” (Tiếng Anh: bus) đến nơi được gắn vào để tìm bộ đệm dữ liệu nằm tại các địa chỉ bộ nhớ vật lý; bất kể các “xe” có một đơn vị quản lý bộ nhớ cho I / O, chuyển đổi không thể dừng lại nếu một lỗi trang xảy ra và sau đó khởi động lại khi có lỗi trang đã được xử lý.
Trong các hệ thống điều hành của IBM dành cho System/370 và hệ thống kế thừa, thuật ngữ này là "cố định", và các trang như vậy có thể được cố định dài hạn, hoặc có thể là cố định ngắn hạn, hoặc có thể không cố định. Cấu trúc điều khiển hệ thống này thường cố định dài hạn (đo trong thời gian của đồng hồ treo tường, tức là, thời gian đo bằng giây, chứ không phải là thời gian đo bằng phần trăm một giây) trong khi bộ đệm I/O thường là cố định ngắn hạn (được đo chục mili giây). Thật vậy, hệ điều hành có một nơi đặc biệt cho "sửa chữa nhanh" những bộ đệm dữ liệu được cố định ngắn hạn (sửa chữa được thực hiện mà không đến hướng dẫn Giám sát hàm gọi tốn thời gian).
Multics sử dụng thuật ngữ "có dây". OpenVMS và Windows chỉ những trang tạm thời  “không có trang” (như đối với bộ đệm I/O) là "bị khóa", và chỉ đơn giản là "nonpageable" cho những cái hoàn toàn không có trang.

Hoạt động ảo-thực

Trong OS / VS1 và các hệ điều hành tương tự, một số bộ phận của hệ thống bộ nhớ được quản lý theo chế độ "ảo-thực", còn gọi là "V = R". Trong chế độ này, mỗi địa chỉ ảo tương ứng với cùng địa chỉ thực. Chế độ này được sử dụng cho các cơ chế ngắt, cho giám sát trang và bảng trang trong hệ thống cũ, và cho các chương trình sử dụng hệ thống quản lý I/O không đúng tiêu chuẩn. Ví dụ, IBM z/OS có 3 chế độ (ảo-ảo, ảo-thực và ảo - cố định).

Thrashing

Khi trang và “cắp” trang (Tiếng Anh: page stealing) đều xảy ra, một vấn đề gọi là "Thrashing" có thể xảy ra, trong đó các máy tính dành một lượng lớn thời gian không thích hợp khi chuyển trang đến và đi từ một nơi sao lưu, do đó làm chậm công việc có ích. Một bộ nhiệm vụ là một bộ tối thiểu của các trang mà phải ở trong bộ nhớ để nó thực hiện những tiến trình hữu ích. Thrashing xảy ra khi không có đủ bộ nhớ để lưu trữ các bộ làm việc của tất cả các chương trình đang hoạt động. Thêm bộ nhớ thực là phản hồi đơn giản nhất, nhưng  việc cải tiến thiết kế ứng dụng, lập chương trình, và sử dụng bộ nhớ cũng có thể giúp. Một giải pháp khác là để giảm số lượng các nhiệm vụ đang hoạt động trên hệ thống. Điều này làm giảm nhu cầu về bộ nhớ thực bằng cách trao đổi các thiết lập toàn bộ hoạt động của một hoặc nhiều quy trình.

Bộ nhớ ảo phân đoạn

Một số hệ thống, chẳng hạn như Burroughs B5500, sử dụng phân đoạn thay vì phân trang, chia các địa chỉ ảo thành các đoạn có độ dài biến. Một địa chỉ ảo bao gồm một chỉ số đoạn và một phần bù (segment + offset). Intel 80286 hỗ trợ một dự án tương tự, nhưng nó hiếm khi được sử dụng. Phân đoạn và phân trang cũng có thể dung chung với nhau bằng cách chia mỗi đoạn thành các trang; các hệ thống sử dụng cấu trúc bố nhớ như vậy, chẳng hạn như Multics và IBM System/38, thường là phân trang ưu tiên,phân đoạn và cung cấp bảo mật bộ nhớ.
Trong Intel 80386 và những bộ xử lý IA-32 sau này, các đoạn nằm trong một khoảng địa chỉ tuyến tính đã được phân trang. Các đoạn có thể được di chuyển vào trong hay ra ngoài khoảng đó; những trang có thể "phân trang" ra hay vào trong bộ nhớ chính, cung cấp 2 mức độ của bộ nhớ ảo; một số ít hệ điều hành sử dụng như vậy thay cho việc chỉ dùng phân trang. Những giải phát cho thiết bị x86 ảo hóa phi phần cứng kết hợp phân trang và phân đoạn bởi vì việc phân trang cho x86 cần có hai miền bảo vệ, trong khi một VMM / hệ điều hành khách / chương trình khách cần đến ba miền. Sự khác biệt giữa hệ thốn phân trang và phân đoạn thống không chỉ là về sự phân chia bộ nhớ; phân đoạn có thể nhìn thấy được trong tiến trình của người dùng, như một phần của mô hình bộ nhớ. Vì vậy, thay vì để bộ nhớ trông như một khoảng không rộng lớn, nó được cấu trúc lại và phân tách thành nhiều không gian nhỏ hơn.
Sự khác biệt này có những hậu quả quan trọng; một phân đoạn không phải là một trang với chiều dài biến hoặc một cách để tăng độ dài địa chỉ. Phân đoạn có thể cung cấp một mô hình bộ nhớ đơn mà trong nó không có sự phân biệt giữa bộ nhớ xử lý và tập tin hệ thống bao gồm duy nhất một danh sách các đoạn (tập tin) được ánh xạ vào không gian địa chỉ
Điều này không giống như các cơ chế được cung cấp bởi các phép gọi như mmap và MapViewOfFile của Win32, bởi vì các con trỏ trong tập tin không hoạt động khi ánh xạ các tập tin trong một khoảng tùy ý. Trong Multics, một tập tin (hay một đoạn trong tập tin gồm nhiều đoạn) được ánh xạ vào một đoạn trong địa chỉ, vì thế các tập tin luôn được ánh xa tại một ranh giới phân đoạn. Phần liên kết của một tập tin có thể chứa con trỏ mà một truy cập để truyền dữ liệu từ con trỏ tới thanh ghi hoặc tạo một tham chiếu gián tiếp qua nó sẽ tạo ra một cái bẫy. Một con trỏ chưa được giải quyết chứa một chỉ dẫn đến tên đoạn mà con trỏ trỏ tới và một vị trí trong phân đoạn; bộ xử lý cho cái bẫy ánh xạ phân đoạn vào địa chỉ, đặt chỉ số phân đoạn vào con trỏ, thay đổi thẻ trong con trỏ sao cho nó không còn tạo ra bẫy và trả về đoạn mã đã gây ra bẫy, tái thi hành các chỉ dẫn đã gây ra bẫy. Điều này loại bỏ hoàn toàn sự cần thiết của một liên kết và hoạt động khi các tiến trình ánh xạ đến cùng một tập tin vào những khoảng khác nhau trong địa chỉ của chúng.

Sự hoán đổi vùng địa chỉ

Một số hệ điều hành cung cấp cho việc hoán đổi toàn bộ vùng địa chỉ, ngoài ra với bất cứ công cụ họ có để phân trang và phân đoạn. Khi điều này xảy ra, hệ điều hành viết những trang và  phân đoạn hiện đang ở trong bộ nhớ chính để thực hiện việc hoán đổi tập tin. Ở sự trao đổi vào, hệ điều hành sẽ đọc lại những dữ liệu từ các tập tin hoán đổi nhưng nó không tự động đọc lại các trang mà được phân trang tại thời điểm hoạt động hoán đổi đang diễn ra.
Nhiều bộ nhớ ảo của IBM, từ OS/VS2 Release 2 tới z/OS, cung cấp cho khả năng đánh dấu một vùng địa chỉ không thể hoán đổi được; làm như vậy để không phải đánh dấu trang nào vào vùng địa chỉ. Điều này có thể được thực hiện trong suốt thời gian của một công việc bằng cách nhập tên của một chương trình chính đủ điều kiện trong bảng đặc tính của chương trình với một lá cờ không hoán đổi được. Thêm vào đó, mã đặc quyền có thể tạm thời làm một vùng địa chỉ không thể hoán đổi được với một lệnh gọi chương trình giám sát SYSEVENT; một vài thay đổi nhất định trong thuộc tính của các vùng địa chỉ đòi hỏi hệ điều hành phải hoán đổi chúng ra rồi lại hoán đổi chúng vào trong lại bằng cách sử dụng SYSEVENT TRANSWAP.