Windows cho biết RAM đã hết trong khi vẫn còn 4 GB bộ nhớ vật lý


24

Ảnh chụp màn hình thông tin hệ thống từ Process Explorer

Thông tin hệ thống này là từ Process Explorer. Vẫn còn bộ nhớ vật lý nhưng hệ thống hiển thị gần như không còn RAM.

Trình quản lý tác vụ cũng cho thấy khoảng 74% tổng RAM được sử dụng.

Kể từ khi cài đặt Windows 8.1, máy tính có RAM 4 + 8 = 12 GB. Tôi đã nâng cấp nó bằng cách thay đổi 4 GB thành mô-đun 8 GB. Có thể đó là vấn đề? Hay hành vi này là bình thường và tôi vừa hiểu nhầm ý nghĩa của bộ nhớ vật lý có sẵn?


Hình ảnh anh ấy cố gắng đính kèm ở đây: tinypic.com/view.php?pic=npon5c&s=8#.Va3P3_lVhBc Tôi đã chấp thuận chỉnh sửa để thêm URL này, nhưng dường như điều đó là không đủ.
Jamie Hanrahan

@JamieHanrahan: Hình ảnh nên được tải lên bằng Ctrl+Gphím tắt để Stack Exchange có thể giữ cho chúng không bị mục nát theo thời gian.
Deltik 21/07/2015

@Deltik Đó không phải là hình ảnh của tôi để tải lên.
Jamie Hanrahan

@JamieHanrahan - Sau khi câu hỏi được gửi, tài liệu đã được chỉ định giấy phép, hình ảnh là các cộng đồng tại thời điểm này ..
Ramhound

Lưu ý để tham khảo trong tương lai, cảm ơn. Tôi chỉ đơn giản nhìn thấy liên kết đến trang web tinypic trong một chỉnh sửa được đề xuất và tôi đã chấp thuận chỉnh sửa đó, nhưng nó không có hiệu lực.
Jamie Hanrahan

Câu trả lời:


65

Câu trả lời ngắn

Cửa sổ bật lên "hết bộ nhớ" cho biết bạn đã hết giới hạn đối với bộ nhớ được cam kết riêng tư , một loại bộ nhớ ảo. Không phải là bạn sắp hết RAM (bộ nhớ vật lý). Không quan trọng bạn có bao nhiêu RAM khả dụng . Có nhiều RAM khả dụng không cho phép bạn vượt quá giới hạn cam kết. Giới hạn cam kết là tổng của tổng RAM của bạn (cho dù có sử dụng hay không!) Cộng với kích thước trang hiện tại của bạn.

Ngược lại, giới hạn cam kết "sử dụng hết" (phần lớn là tạo không gian địa chỉ ảo riêng tư quy trình) không nhất thiết phải sử dụng bất kỳ RAM nào! Nhưng HĐH sẽ không cho phép tạo ra nó trừ khi nó biết có nơi nào đó để lưu trữ nếu cần. Vì vậy, bạn có thể chạy vào giới hạn cam kết mà không cần sử dụng tất cả RAM, hoặc thậm chí hầu hết RAM.

Đây là lý do tại sao bạn không nên chạy mà không có pagefile. Lưu ý rằng pagefile có thể không thực sự được ghi vào! Nhưng nó vẫn sẽ cho phép bạn tránh các lỗi "thiếu bộ nhớ" và "hết bộ nhớ".

Trả lời trung gian

Windows thực sự không có thông báo lỗi vì hết RAM. Những gì bạn sắp hết là "giới hạn cam kết".

Biểu đồ "Hệ thống" trong phiên bản Process Explorer đó được đặt tên kém. Nó nên được dán nhãn "phí cam kết". (Trong phiên bản tôi có tên là "Cam kết hệ thống". Tốt hơn, nhưng vẫn không hoàn toàn nhất quán.) Trong mọi trường hợp, chiều cao "hiện tại" của biểu đồ có phần hiển thị thấp hơn trong phần văn bản là "Cam kết phí" - " Hiện tại "và chiều cao tối đa của biểu đồ biểu thị" Phí cam kết "-" Giới hạn ".

"Cam kết phí" đề cập đến không gian địa chỉ ảo được hỗ trợ bởi tệp trang (nếu bạn có) - nói cách khác, nếu không thể phù hợp với RAM, phần còn lại sẽ nằm trong tệp trang. (Có các loại vas khác được hỗ trợ bởi các tệp khác - được gọi là vas "được ánh xạ" - hoặc phải ở trong RAM mọi lúc; loại sau được gọi là "không thể truy cập được". "Giới hạn cam kết" là mức tối đa "phí cam kết" có thể được. Nó bằng với kích thước RAM của bạn cộng với kích thước tệp trang.

Bạn rõ ràng không có pagefile (tôi có thể nói vì giới hạn cam kết của bạn bằng với kích thước RAM của bạn), vì vậy giới hạn cam kết chỉ đơn giản là kích thước RAM.

Rõ ràng các chương trình khác nhau + HĐH đã sử dụng gần như tất cả các cam kết tối đa có thể.

Điều này không có gì trực tiếp để làm với bao nhiêu RAM là miễn phí hoặc có sẵn. Có, bạn có khoảng 4,5 GB RAM có sẵn. Điều đó không có nghĩa là bạn có thể vượt quá giới hạn cam kết. Bộ nhớ cam kết không nhất thiết phải sử dụng RAM và không bị giới hạn bởi dung lượng RAM khả dụng.

Bạn cần kích hoạt lại tệp trang - bằng cách sử dụng nhiều cam kết này, tôi sẽ đề xuất tệp trang 16 GB, vì bạn không muốn hệ điều hành giữ quá nhiều thứ đó trong RAM và tệp trang hoạt động tốt nhất nếu nó có rất nhiều phòng miễn phí - hoặc nếu không thì thêm RAM. Hơn rất nhiều. Để có hiệu suất tốt, bạn cần có nhiều dung lượng RAM cho mã và các thứ khác không được hỗ trợ bởi pagefile (nhưng có thể được phân trang ra các tệp khác).

Câu trả lời rất dài

(nhưng vẫn ngắn hơn rất nhiều so với chương quản lý bộ nhớ của Windows Internals ...)

Giả sử một chương trình phân bổ 100 MB bộ nhớ ảo xử lý riêng. Điều này được thực hiện với một cuộc gọi VirtualAlloc với tùy chọn "cam kết". Điều này sẽ dẫn đến sự gia tăng 100 MB trong "Phí cam kết". Nhưng "phân bổ" này không thực sự sử dụng bất kỳ RAM! RAM chỉ được sử dụng khi một số không gian địa chỉ ảo được cam kết mới được truy cập lần đầu tiên.

Làm thế nào RAM cuối cùng được sử dụng

(nếu có)

Truy cập lần đầu vào không gian mới được cam kết gần như luôn luôn là ghi bộ nhớ (đọc các vas riêng mới được phân bổ trước khi viết nó gần như luôn luôn là một lỗi lập trình, vì nội dung ban đầu của nó, nói đúng, không xác định). Nhưng đọc hoặc viết, kết quả, lần đầu tiên bạn chạm vào một trang của các vas mới được phân bổ, là một lỗi trang . Mặc dù từ "lỗi" nghe có vẻ tệ, nhưng lỗi trang là một sự kiện hoàn toàn được mong đợi và thậm chí là bắt buộc trong hệ điều hành bộ nhớ ảo.

Để đối phó với loại lỗi trang cụ thể này, máy nhắn tin (một phần của trình quản lý bộ nhớ của HĐH, đôi khi tôi sẽ viết tắt là "Mm") sẽ:

  1. phân bổ một trang vật lý của RAM (lý tưởng nhất là từ danh sách trang 0, nhưng trong mọi trường hợp, nó xuất phát từ những gì Windows gọi là "có sẵn": Danh sách trang không, miễn phí hoặc dự phòng, theo thứ tự ưu tiên đó);
  2. điền vào một mục trong bảng trang để liên kết trang vật lý với trang ảo; và cuối cùng
  3. loại bỏ ngoại lệ lỗi trang.

Sau đó, mã đã tham chiếu bộ nhớ sẽ thực hiện lại lệnh đã đưa ra lỗi trang và lần này tham chiếu sẽ thành công.

Chúng tôi nói rằng trang đã bị "lỗi" trong bộ quy trình làm việc và vào RAM. Trong Trình quản lý tác vụ, phần này sẽ xuất hiện dưới dạng tăng một trang (4 KB) trong "bộ làm việc riêng" của quy trình. Và giảm một trang trong bộ nhớ vật lý có sẵn. (Cái sau có thể khó nhận thấy trên một máy bận.)

Lưu ý 1: Lỗi trang này không liên quan đến bất cứ điều gì đọc từ đĩa. Một trang chưa bao giờ được truy cập của bộ nhớ ảo đã cam kết không bắt đầu cuộc sống trên đĩa; nó không có chỗ đứng trên đĩa để đọc nó từ . Nó chỉ đơn giản là "vật chất hóa" trong một trang RAM có sẵn trước đó. Trên thực tế, hầu hết các lỗi trang được giải quyết trong RAM, đối với các trang được chia sẻ đã có RAM cho các quy trình khác hoặc lưu trữ trang - danh sách chờ hoặc danh sách đã sửa đổi hoặc là các trang "không yêu cầu" như trang này.

Lưu ý 2: Điều này chỉ mất một trang, 4096 byte, từ "Có sẵn". Không gian địa chỉ đã cam kết chưa từng được chạm vào thường được nhận ra là lỗi của Haiti chỉ mỗi lần một trang, vì mỗi trang được "chạm" lần đầu tiên. Sẽ không có cải thiện, không có lợi thế, trong việc làm nhiều hơn tại một thời điểm; nó sẽ chỉ mất n lần. Ngược lại, khi các trang phải được đọc từ đĩa, một số lượng "readahead" được thử vì phần lớn thời gian trong một lần đọc đĩa nằm trong chi phí hoạt động, không phải truyền dữ liệu thực tế. Số tiền "đã cam kết" duy trì ở mức 100 MB; thực tế là một hoặc các trang đã bị lỗi không làm giảm phí cam kết.

Lưu ý 3:Giả sử rằng chúng ta có RAM 4 GB "có sẵn". Điều đó có nghĩa là chúng ta có thể tham chiếu bộ nhớ đã cam kết đã được phân bổ nhưng chưa bao giờ được tham chiếu trước khoảng một triệu lần nữa (4 GB / 4096) trước khi chúng ta hết RAM. Tại thời điểm đó, nếu chúng ta có một trang như David Cutler và Lou Perazzoli dự định, một số trang được tham chiếu lâu nhất trong RAM sẽ được lưu trên đĩa và sau đó được sử dụng để giải quyết các lỗi trang gần đây hơn này. (Trên thực tế, HĐH sẽ khởi tạo các phương thức cải tạo RAM như "cắt xén bộ công việc" thay vì trước đó và ghi thực tế vào tệp trang được lưu vào bộ đệm và được liệt kê trong danh sách trang đã sửa đổi để hiệu quả và ...) Không ai trong số đó ảnh hưởng đến "cam kết" tính. Tuy nhiên, nó có liên quan đến "giới hạn cam kết". Nếu không có chỗ cho tất cả "

Và nó cứ xảy ra ...

Nhưng hãy giả sử rằng chúng tôi đã không thực hiện thêm hàng triệu tài liệu tham khảo đó và vẫn còn khoảng 4GB trang có giá trị "có sẵn". Bây giờ, giả sử quy trình tương tự - hoặc một quy trình khác, không thành vấn đề - thực hiện một VirtualAlloc khác, lần này là 200 MB đã cam kết. Một lần nữa, 200 MB này được thêm vào phí cam kết và nó không xóa bất kỳ RAM nào. Đơn giản là không gian địa chỉ của VirtualAlloc không sử dụng hết một lượng RAM tương ứng và việc có RAM "khả dụng" thấp sẽ không giới hạn dung lượng địa chỉ mà bạn có thể VirtualAlloc (cũng không có RAM khả dụng cao làm tăng nó).

(Chà, ok ... có một chút chi phí nhỏ, lên tới một trang (có thể phân trang!) Được sử dụng cho một bảng trang cho mỗi 2 MB (4 MB nếu bạn sử dụng hệ thống x86, không PAE) của không gian địa chỉ ảo được phân bổ và có một "mô tả địa chỉ ảo" gồm vài chục byte cho mỗi phạm vi được phân bổ gần như liền kề.)

Theo cách này là có thể - và phổ biến! - để sử dụng nhiều "phí cam kết" trong khi chỉ sử dụng một lượng nhỏ RAM.

Vì vậy, nếu "cam kết" không gian địa chỉ ảo không sử dụng hết RAM, tại sao phải có giới hạn?

Bởi vì "phí cam kết" thể hiện tiềm năng sử dụng không gian lưu trữ trong tương lai . "Giới hạn cam kết" biểu thị tổng dung lượng lưu trữ (RAM + dung lượng trang) có sẵn để giữ các phân bổ như vậy, nếu chúng thực sự được tham chiếu và từ đó cần được lưu trữ ở đâu đó.

Khi Mm chấp thuận yêu cầu VirtualAlloc, điều đó đầy hứa hẹn - "thực hiện cam kết" - rằng tất cả các bộ nhớ tiếp theo truy cập vào khu vực được phân bổ sẽ thành công; chúng có thể dẫn đến lỗi trang nhưng tất cả các lỗi sẽ có thể được giải quyết, bởi vì có đủ dung lượng lưu trữ để giữ nội dung của tất cả các trang đó, cho dù là trong RAM hay trong tệp trang. Mm biết điều này bởi vì nó biết có bao nhiêu dung lượng lưu trữ (giới hạn cam kết) và bao nhiêu đã được "cam kết" (phí cam kết hiện tại).

(Nhưng tất cả các trang đó chưa nhất thiết phải được truy cập, do đó, không nhất thiết phải có một dung lượng lưu trữ phù hợp với số tiền đã cam kết, tại bất kỳ thời điểm nào.)

Vậy ... Thế còn "hệ thống hết bộ nhớ" thì sao?

Nếu bạn cố gắng VirtualAlloc và khoản phí cam kết hiện tại cộng với kích thước phân bổ được yêu cầu sẽ đưa bạn vượt quá giới hạn cam kết, VÀ HĐH không thể mở rộng tệp trang để tăng giới hạn cam kết ... bạn sẽ nhận được thông báo "hết bộ nhớ" lên và quá trình thấy Virtual ALLoc gọi FAIL. Hầu hết các chương trình sẽ chỉ giơ tay và chết tại thời điểm đó. Một số người sẽ nhấn nút một cách mù quáng, cho rằng cuộc gọi đã thành công và thất bại sau đó khi họ cố gắng tham chiếu khu vực mà họ nghĩ rằng họ đã phân bổ.

Một lần nữa (xin lỗi vì sự lặp lại): không quan trọng bạn có bao nhiêu RAM. HĐH đã hứa rằng RAM hoặc dung lượng trang sẽ có sẵn khi cần, nhưng lời hứa đó không trừ đi "Có sẵn". RAM có sẵn chỉ được sử dụng bởi vm đã cam kết khi nó được tham chiếu lần đầu tiên, đó là nguyên nhân khiến nó bị "lỗi" ... tức là nhận ra trong bộ nhớ vật lý. Và chỉ đơn giản là cam kết (= phân bổ) bộ nhớ ảo không làm điều đó. Nó chỉ lấy không gian địa chỉ ảo miễn phí và làm cho không gian địa chỉ ảo có thể sử dụng được.

Nhưng trong trường hợp "hết bộ nhớ", đã có một yêu cầu phân bổ cho bộ nhớ đã cam kết và HĐH đã thêm phí cam kết hiện tại vào kích thước của yêu cầu mới này ... và thấy rằng tổng số vượt quá giới hạn cam kết. Vì vậy, nếu HĐH chấp thuận cái mới này tất cả không gian đó đã được tham chiếu sau đó, sẽ không có bất kỳ vị trí thực sự nào (RAM + tệp trang) để lưu trữ tất cả.

HĐH sẽ không cho phép điều này. Nó sẽ không cho phép nhiều vas được phân bổ hơn nó có không gian để giữ nó trong trường hợp xấu nhất - ngay cả khi tất cả trong số đó bị "lỗi". Đó là mục đích của "giới hạn cam kết".

Tôi nói với bạn ba lần Tôi nói với bạn ba lần Tôi nói với bạn ba lần: Dung lượng RAM "Có sẵn" không thành vấn đề. Không gian ảo đã cam kết không thực sự sử dụng tất cả không gian lưu trữ đó, không thành vấn đề. Windows không thể "cam kết" với phân bổ ảo trừ khi tất cả '' có thể '' bị lỗi trong tương lai.

Lưu ý rằng có một loại vas khác gọi là "ánh xạ", chủ yếu được sử dụng cho mã và để truy cập vào các tệp dữ liệu lớn, nhưng nó không bị tính phí cho "phí cam kết" và không bị giới hạn bởi "giới hạn cam kết". Điều này là do nó đi kèm với vùng lưu trữ riêng của nó, các tệp được "ánh xạ" tới nó. Giới hạn duy nhất đối với các vas "được ánh xạ" là dung lượng ổ đĩa bạn có cho các tệp được ánh xạ và lượng vas miễn phí trong quy trình của bạn để ánh xạ chúng vào.

Nhưng khi tôi nhìn vào hệ thống, tôi chưa hoàn toàn ở giới hạn cam kết?

Về cơ bản đó là một vấn đề đo lường và lưu giữ hồ sơ. Bạn đang xem hệ thống sau khi một cuộc gọi VirtualAlloc đã được thử và thất bại.

Giả sử bạn chỉ còn 500 MB giới hạn cam kết và một số chương trình đã cố gắng Virtual ALLoc 600 MB. Nỗ lực thất bại. Sau đó, bạn nhìn vào hệ thống và nói "Cái gì? Vẫn còn 500 MB!" Trong thực tế có thể còn rất nhiều điều còn sót lại sau đó, bởi vì quá trình được đề cập có thể đã hoàn toàn biến mất vào thời điểm đó, vì vậy TẤT CẢ bộ nhớ đã cam kết được phân bổ trước đó của nó đã được phát hành.

Vấn đề là bạn không thể nhìn lại thời gian và xem phí cam kết là gì tại thời điểm nỗ lực phân bổ được thực hiện. Và bạn cũng không biết nỗ lực dành cho bao nhiêu không gian. Vì vậy, bạn không thể chắc chắn thấy lý do tại sao nỗ lực thất bại hoặc cần bao nhiêu "giới hạn cam kết" để cho phép nó hoạt động.

Tôi đã nhìn thấy "hệ thống đang chạy thấp trên bộ nhớ". Cái gì vậy

Nếu trong trường hợp trên, HĐH CÓ THỂ mở rộng tệp trang (nghĩa là bạn để nó ở cài đặt "hệ thống được quản lý" mặc định hoặc bạn quản lý nó nhưng bạn đặt tối đa thành lớn hơn ban đầu, VÀ có đủ dung lượng đĩa trống) và việc mở rộng như vậy làm tăng giới hạn cam kết đủ để cho cuộc gọi VirtualAlloc thành công, sau đó ... Mm mở rộng tệp trang và cuộc gọi VirtualAlloc thành công.

Và đó là khi bạn thấy "hệ thống đang chạy THẤP trên bộ nhớ". Đó là một cảnh báo sớm rằng nếu mọi thứ tiếp tục mà không giảm thiểu, bạn có thể sẽ sớm thấy cảnh báo "hết bộ nhớ". Thời gian để đóng một số ứng dụng. Tôi sẽ bắt đầu với các cửa sổ trình duyệt của bạn.

Và bạn nghĩ đó là một điều tốt? Mở rộng Pagefile là xấu xa !!!

Không, không phải vậy. Xem, HĐH không thực sự "mở rộng" tệp hiện có. Nó chỉ phân bổ một mức độ mới. Hiệu ứng này giống như bất kỳ tập tin không liền kề nào khác. Các nội dung pagefile cũ giữ đúng vị trí của chúng; họ không cần phải được sao chép đến một nơi mới hoặc bất cứ điều gì tương tự. Vì hầu hết IO của pagefile có khối lượng tương đối nhỏ so với kích thước của pagefile, nên khả năng bất kỳ lần chuyển nào sẽ vượt qua một ranh giới phạm vi là rất hiếm, do đó sự phân mảnh không gây tổn hại nhiều trừ khi nó thực sự quá mức.

Cuối cùng, khi tất cả các quy trình có không gian "đã cam kết" trong tiện ích mở rộng đã thoát (khi tắt hệ điều hành nếu không sớm hơn), các phần mở rộng sẽ được giải phóng một cách âm thầm và pagefile sẽ trở lại kích thước và phân bổ trước đó - nếu nó tiếp giáp trước đó lại như vậy

Do đó, cho phép mở rộng pagefile hoạt động như một mạng an toàn hoàn toàn miễn phí: Nếu bạn cho phép nhưng hệ thống không bao giờ cần đến nó, hệ thống sẽ không "liên tục mở rộng và ký hợp đồng với pagefile" như thường được yêu cầu, do đó sẽ không mất . Và nếu bạn cần nó, nó sẽ cứu bạn khỏi các ứng dụng bị lỗi với lỗi "hết bộ nhớ ảo".

Nhưng nhưng nhưng...

Tôi đã đọc trên hàng chục trang web rằng nếu bạn cho phép mở rộng pagefile, Windows sẽ liên tục mở rộng và ký hợp đồng với pagefile, và điều này sẽ dẫn đến sự phân mảnh của pagefile cho đến khi bạn chống phân mảnh.

Họ chỉ sai thôi.

Nếu bạn chưa bao giờ thấy cửa sổ bật lên "sắp hết bộ nhớ" (hoặc, trong các phiên bản cũ hơn, "sắp hết bộ nhớ ảo"), hệ điều hành chưa bao giờ mở rộng tệp trang của bạn.

Nếu bạn thấy cửa sổ bật lên đó, thì nó sẽ cho bạn biết kích thước tệp trang ban đầu của bạn quá nhỏ. . để chơi

Nhưng tại sao họ không ...

Người ta có thể lập luận rằng HĐH chỉ nên để phân bổ xảy ra và sau đó để các tham chiếu thất bại nếu không có RAM để giải quyết các lỗi trang. Nói cách khác, ở trên, nơi chúng tôi đã mô tả cách hoạt động của lỗi trang ban đầu, điều gì xảy ra nếu việc "phân bổ một trang vật lý có sẵn của RAM" (bước 1) không thể thực hiện được vì không có sẵn không có chỗ còn lại để trang bất cứ điều gì để làm cho có sẵn?

Sau đó, máy nhắn tin sẽ không thể giải quyết lỗi trang. Nó sẽ phải cho phép ngoại lệ (lỗi trang) được báo cáo lại cho luồng bị lỗi, có thể đã thay đổi thành một số mã ngoại lệ khác.

Triết lý thiết kế là VirtualAlloc sẽ trả về 0 (về mặt kỹ thuật là con trỏ NULL) thay vì địa chỉ nếu bạn hết giới hạn cam kết và hoàn toàn hợp lý khi hy vọng lập trình viên biết rằng cuộc gọi VirtualAlloc có thể thất bại. Vì vậy, các lập trình viên dự kiến ​​sẽ kiểm tra trường hợp đó và làm điều gì đó hợp lý để đáp ứng (như cho bạn cơ hội để lưu công việc của bạn đến thời điểm đó, và sau đó kết thúc chương trình một cách "duyên dáng"). (Lập trình viên: Bạn kiểm tra một con trỏ NULL trở về từ malloc, mới, v.v., vâng? Vậy tại sao bạn không từ đây?)

Nhưng các lập trình viên không cần phải mong đợi rằng một tham chiếu bộ nhớ đơn giản như

i = 0;             // initialize loop counter

có thể thất bại - không phải nếu nó nằm trong vùng không gian địa chỉ được cam kết thành công. (Hoặc ánh xạ không gian địa chỉ, đối với vấn đề đó.) Nhưng đó là điều có thể xảy ra nếu triết lý "cho phép phân bổ quá mức, hãy để tham chiếu bộ nhớ không thành công".

Thật không may, một tham chiếu bộ nhớ như mã trong dòng mã ở trên không có cách thuận tiện để trả lại trạng thái xấu! Chúng chỉ được cho là hoạt động , giống như phép cộng và phép trừ. Cách duy nhất để báo cáo những thất bại như vậy sẽ là ngoại lệ. Vì vậy, để xử lý chúng, lập trình viên sẽ phải bọc toàn bộ chương trình trong một trình xử lý ngoại lệ. (thử ... bắt và tất cả những thứ đó.)

Điều đó có thể được thực hiện ... Nhưng thật khó để người xử lý biết cách "làm điều đúng" để đáp ứng với những ngoại lệ đó, vì sẽ có rất nhiều, rất nhiều điểm trong mã mà họ có thể phát sinh. (Cụ thể, chúng có thể phát sinh tại mọi tham chiếu bộ nhớ đến bộ nhớ VirtualAlloc'd, đến bộ nhớ được cấp phát bằng malloc hoặc mới ... và cho tất cả các biến cục bộ, vì ngăn xếp cũng là VirtualAlloc'd.)

Nói tóm lại, làm cho chương trình thất bại một cách duyên dáng trong những trường hợp này sẽ rất khó khăn.

Mặt khác, khá dễ dàng để kiểm tra con trỏ NULL trả về từ VirtualAlloc (hoặc malloc hoặc mới, mặc dù chúng không hoàn toàn giống nhau) và sau đó làm điều gì đó hợp lý ... như không cố gắng đi trên và làm bất cứ điều gì đó là chương trình cần không gian ảo đó. Và có thể hỏi người dùng nếu họ muốn lưu công việc của họ cho đến nay, nếu có. (Cấp, quá nhiều ứng dụng không bận tâm đến mức đó.)

Những người dùng khác của cam kết

Ngẫu nhiên, "giới hạn cam kết" không bị giảm bởi các phân bổ khác nhau của HĐH như nhóm phân trang và nhóm không phân trang, danh sách PFN, v.v.; những thứ này chỉ được tính để cam kết tính phí khi chúng xảy ra. Cũng không phải là phí cam kết hoặc giới hạn cam kết bị ảnh hưởng bởi RAM video, hoặc thậm chí kích thước "cửa sổ" của RAM video.

Tự kiểm tra

Bạn có thể demo tất cả những điều này với công cụ testlimit từ trang SysIternals. Tùy chọn -m sẽ phân bổ không gian địa chỉ đã cam kết nhưng sẽ không "chạm" vào nó, do đó sẽ không gây ra sự phân bổ RAM. Trong khi đó tùy chọn -d sẽ phân bổ và cũng tham chiếu các trang, khiến cả phí cam kết đều tăng và RAM khả dụng giảm.

Tài liệu tham khảo

Windows Internals của Russinovich, Solomon và Ionescu. Thậm chí có những cuộc biểu tình cho phép bạn chứng minh tất cả những điểm này bằng công cụ testlimit. Tuy nhiên, tôi phải cảnh báo bạn rằng nếu bạn nghĩ điều này dài, hãy cảnh báo: riêng chương Mm là 200 trang; ở trên là một phiên bản đơn giản hóa TUYỆT VỜI. (Xin vui lòng lướt qua phần "Lời cảm ơn" trong phần Giới thiệu.)

Xem thêm tài liệu MSDN Virtual ALLoc


4
@AcePL Tôi đã giải thích tại sao. Tóm lại: Điều đó xảy ra vì giới hạn cam kết của anh ta quá thấp so với khối lượng công việc của anh ta. Cam kết giới hạn là tổng kích thước RAM + kích thước trang hiện tại. Lượng RAM "khả dụng" không nhập vào nó. Cơ chế "giới hạn cam kết" sẽ không cho phép phân bổ không gian địa chỉ ảo ngoài khả năng lưu trữ vật lý (RAM + lưu trữ sao lưu trên đĩa, tức là pagefile) để giữ nội dung. Hãy nhớ rằng, mặc dù nó là ảo, nhưng nó phải được giữ ở đâu đó một khi nó bị lỗi lần đầu tiên.
Jamie Hanrahan

5
@AcePL - người dùng không thực sự hết bộ nhớ. Anh ta sắp hết bộ nhớ ảo. Giải thích này là hợp lệ 100%.
Ramhound

1
@Rahul Basu Thật ra tôi sẽ mong nhận xét ngắn sẽ khó hiểu hơn nhiều. ;) Câu hỏi này và nhiều câu hỏi tương tự là bằng chứng cho thấy nhiều người có một số hiểu lầm sâu sắc về bộ nhớ ảo, không gian địa chỉ, bộ làm việc, v.v. Không phải lỗi của họ - đó là một chủ đề rất phức tạp và màn hình của MS chưa bao giờ rõ ràng như họ có thể . Nhưng phải mất rất nhiều từ để giải thích thậm chí là một phần của nó. Các của Windows Internals không có sơ đồ, mà giúp đỡ. Các sơ đồ hoạt hình sẽ còn tuyệt vời hơn nữa ...
Jamie Hanrahan

3
Có thể quan tâm: "chỉ cần để phân bổ xảy ra và sau đó để tham chiếu thất bại nếu không có RAM để khắc phục lỗi trang" tương tự như những gì Linux làm theo mặc định: nó cho phép một số lượng dư thừa nhất định, nhưng tại một số điểm sẽ hết bộ nhớ ảo cho các trang bẩn và đó là khi kẻ giết người hết bộ nhớ tấn công ... và giết chết những gì có thể là một quá trình hoàn toàn không liên quan . Vâng, khó chịu.
Bob

1
@JamieHanrahan Hình như bạn đã làm (xin lỗi, hơi bận). Có, overcommit có thể cấu hình được và một số distro sẽ vô hiệu hóa nó. Nhưng có vẻ như nó vẫn còn phổ biến trong năm 20132014 , và tôi tin rằng đó là mặc định kernel khi không được đặt rõ ràng (bởi distro hoặc bởi người dùng).
Bob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.