Khi một forks quá trình là bộ nhớ ảo hoặc bộ nhớ thường trú của nó được sao chép?


12

Cách tiêu chuẩn để tạo các tiến trình mới trong Linux là dấu chân bộ nhớ của tiến trình cha được sao chép và trở thành môi trường của tiến trình con cho đến khi execvđược gọi.

Chúng ta đang nói về dấu chân bộ nhớ nào, ảo (quá trình yêu cầu) hoặc cư dân (những gì thực sự đang được sử dụng)?

Động lực: Tôi có một thiết bị có không gian hoán đổi hạn chế và một ứng dụng có sự khác biệt lớn giữa dấu chân ảo và bộ nhớ thường trú. Ứng dụng không thể rẽ nhánh do thiếu bộ nhớ và muốn xem nếu cố gắng giảm kích thước dấu chân ảo sẽ giúp ích.

Câu trả lời:


12

Trong các hệ thống hiện đại, không có bộ nhớ nào thực sự được sao chép chỉ vì một cuộc gọi hệ thống ngã ba được sử dụng. Tất cả được đánh dấu chỉ đọc trong bảng trang sao cho lần thử đầu tiên viết bẫy vào mã kernel sẽ xảy ra. Chỉ khi quá trình đầu tiên cố gắng viết, việc sao chép sẽ xảy ra.

Điều này được gọi là sao chép trên ghi.

Tuy nhiên, có thể cần phải theo dõi không gian địa chỉ đã cam kết. Nếu không có bộ nhớ hoặc trao đổi có sẵn tại thời điểm kernel phải sao chép một trang, nó phải giết một số tiến trình để giải phóng bộ nhớ. Điều này không phải lúc nào cũng mong muốn, vì vậy có thể theo dõi lượng bộ nhớ mà kernel đã cam kết.

Nếu hạt nhân sẽ cam kết nhiều hơn bộ nhớ có sẵn + trao đổi, nó có thể đưa ra mã lỗi khi cố gắng gọi fork. Nếu đủ có sẵn, kernel sẽ cam kết kích thước ảo đầy đủ của cha mẹ cho cả hai quá trình sau khi rẽ nhánh.


1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.Vâng, cảm ơn. Có nghĩa là việc giảm dấu chân ảo của quá trình trong môi trường có bộ nhớ hạn chế (RAM và trao đổi) có thể giải quyết vấn đề không thể rẽ nhánh.
TheMeaningfulEngineer

1
@Alan Có. Nếu forkthất bại với thông báo lỗi cho biết bộ nhớ không đủ. Sau đó, giảm việc sử dụng bộ nhớ ảo của quá trình trước khi rèn có thể giúp ích.
kasperd

5

Đừng lo lắng, nó tạo ra một bản sao lười biếng (copy-on-write). Các địa chỉ bộ nhớ ảo của cả hai quá trình ban đầu chỉ đến cùng một trang, nhưng khi quá trình rẽ nhánh cố gắng sửa đổi nó, nó thực sự tạo ra một bản sao vật lý của trang (từ đó trở đi, trang đó nằm ở hai vị trí trong RAM của bạn).

Coi chừng, không có dấu chân bộ nhớ được báo cáo nào thực sự cho bạn biết quá trình sử dụng RAM là bao nhiêu. Do hoán đổi, chia sẻ bộ nhớ và các vấn đề khác với bộ nhớ ảo, không thể biết chắc chắn. Một số phần của không gian bộ nhớ là các thư viện dùng chung (đếm chúng ở đâu?), Một số đề cập đến bộ nhớ không phải RAM (các thiết bị phần cứng khác), một số hiện đang bị tráo đổi, một số chưa được sao chép (sao chép trên ghi) và Sớm. Đọc này:

https://lwn.net/Articles/642202/


5

Có cài đặt kernel

/ Proc / sys / vm / overcommit_memory

Trích dẫn từ bài viết xuất sắc :

Since 2.5.30 the values are: 0 (default): as before: guess about how much  
overcommitment is reasonable, 1: never refuse any malloc(), 2: be precise 
about the overcommit - never commit a virtual address space larger than swap 
space plus a fraction overcommit_ratio of the physical memory. Here 
/proc/sys/vm/overcommit_ratio (by default 50) is another user-settable 
parameter. It is possible to set overcommit_ratio to values larger than 100. 
(See also Documentation/vm/overcommit-accounting.)

Điều này áp dụng cho dĩa cũng như malloc thông thường. Tức là nếu bạn đặt nó thành 0, fork sẽ được sao chép khi ghi. Sao chép trên ghi có nghĩa là một khi ứng dụng rẽ nhánh, cả hai bản sao sẽ chia sẻ các trang bộ nhớ sử dụng con hoặc bản gốc bắt đầu thay đổi bộ nhớ.

Trong hầu hết các bản phân phối tôi biết overcommit là 0. Nhưng nếu bạn đặt nó thành 2, tất cả các trang bộ nhớ sẽ được hỗ trợ đầy đủ bởi bộ nhớ thực và trong một số trường hợp dưới áp suất bộ nhớ cao sẽ ổn định hơn, nhưng một số chương trình (tôi phải đối mặt với gitk) trên overcommits sẽ thất bại.

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.