Nó có thể.
Có hai điều kiện bộ nhớ khác nhau mà bạn có thể gặp trong Linux. Mà bạn gặp phải phụ thuộc vào giá trị của sysctl vm.overcommit_memory
( /proc/sys/vm/overcommit_memory
)
Giới thiệu:
Hạt nhân có thể thực hiện cái được gọi là 'overcommit'. Đây là khi kernel phân bổ các chương trình nhiều bộ nhớ hơn thực sự có trong hệ thống. Điều này được thực hiện với hy vọng rằng các chương trình sẽ không thực sự sử dụng tất cả bộ nhớ mà chúng phân bổ, vì đây là một sự cố khá phổ biến.
overcommit_memory = 2
Khi overcommit_memory
được đặt thành 2
, kernel hoàn toàn không thực hiện bất kỳ sự thừa nào. Thay vào đó khi một chương trình được cấp phát bộ nhớ, nó được đảm bảo quyền truy cập để có bộ nhớ đó. Nếu hệ thống không có đủ bộ nhớ trống để đáp ứng yêu cầu cấp phát, kernel sẽ trả về lỗi cho yêu cầu. Đó là tùy thuộc vào chương trình để xử lý tình huống duyên dáng. Nếu nó không kiểm tra việc phân bổ thành công khi nó thực sự thất bại, ứng dụng sẽ thường gặp phải một segfault.
Trong trường hợp của segfault, bạn nên tìm một dòng như thế này trong đầu ra của dmesg
:
[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]
Điều at 0
đó có nghĩa là ứng dụng đã cố gắng truy cập một con trỏ chưa được khởi tạo, đây có thể là kết quả của một cuộc gọi cấp phát bộ nhớ không thành công (nhưng đó không phải là cách duy nhất).
overcommit_memory = 0 và 1
Khi overcommit_memory
được đặt thành 0
hoặc 1
, overcommit được bật và các chương trình được phép phân bổ nhiều bộ nhớ hơn mức thực sự có sẵn.
Tuy nhiên, khi một chương trình muốn sử dụng bộ nhớ đã được cấp phát, nhưng kernel thấy rằng nó không thực sự có đủ bộ nhớ để đáp ứng, nó cần lấy lại bộ nhớ. Đầu tiên, nó cố gắng thực hiện các tác vụ dọn dẹp bộ nhớ khác nhau, chẳng hạn như xóa bộ nhớ cache, nhưng nếu điều này là không đủ thì nó sẽ chấm dứt một quá trình. Việc chấm dứt này được thực hiện bởi OOM-Killer. OOM-Killer nhìn vào hệ thống để xem các chương trình đang sử dụng bộ nhớ nào, chúng đã chạy được bao lâu, ai đang chạy chúng và một số yếu tố khác để xác định chương trình nào sẽ bị giết.
Sau khi quá trình bị hủy, bộ nhớ mà nó đang sử dụng sẽ được giải phóng và chương trình vừa gây ra tình trạng hết bộ nhớ giờ có bộ nhớ cần thiết.
Tuy nhiên, ngay cả trong chế độ này, các chương trình vẫn có thể bị từ chối yêu cầu phân bổ. Khi overcommit_memory
là 0
, hạt nhân cố gắng để có một đoán tốt nhất tại khi nó nên bắt đầu phủ nhận yêu cầu phân bổ. Khi được đặt thành 1
, tôi không chắc nó sử dụng quyết định nào để xác định khi nào nên từ chối yêu cầu nhưng nó có thể từ chối các yêu cầu rất lớn.
Bạn có thể xem liệu OOM-Killer có liên quan hay không bằng cách xem kết quả đầu ra dmesg
và tìm một thông báo như:
[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB