Kẻ giết người OOM không hoạt động?


41

Đối với những gì tôi hiểu, khi hệ thống gần không có bộ nhớ trống, kernel sẽ bắt đầu tiêu diệt các tiến trình để lấy lại bộ nhớ. Nhưng trong hệ thống của tôi, điều này hoàn toàn không xảy ra.

Giả sử một tập lệnh đơn giản chỉ phân bổ nhiều bộ nhớ hơn mức có sẵn trong hệ thống (ví dụ, một mảng có hàng triệu chuỗi). Nếu tôi chạy một tập lệnh như thế này (như một người dùng bình thường), nó chỉ nhận được tất cả bộ nhớ cho đến khi hệ thống đóng băng hoàn toàn (chỉ SysRQ REISUB hoạt động).

Điều kỳ lạ ở đây là khi máy tính đóng băng, đèn led ổ cứng bật và giữ nguyên như vậy cho đến khi máy tính được khởi động lại, dù tôi có gắn phân vùng trao đổi hay không!

Vì vậy, câu hỏi của tôi là:

  1. Hành vi này có bình thường không? Thật kỳ lạ khi một ứng dụng được thực thi như một người dùng bình thường có thể làm sập hệ thống theo cách này ...
  2. Có cách nào để tôi có thể khiến Ubuntu tự động hủy các ứng dụng đó khi chúng chiếm quá nhiều (hoặc nhiều nhất) bộ nhớ không?

Thông tin thêm

  • Ubuntu 12.04.3
  • Hạt nhân 3.5.0-44
  • RAM: ~ 3,7GB từ 4GB (dùng chung với card đồ họa). *

    $ tail -n+1 /proc/sys/vm/overcommit_*
    ==> /proc/sys/vm/overcommit_memory <==
    0
    
    ==> /proc/sys/vm/overcommit_ratio <==
    50
    
    $ cat /proc/swaps
    Filename                Type        Size    Used    Priority
    /dev/dm-1                               partition   4194300 344696  -1
    

Tôi không chắc tại sao nó không hoạt động. Hãy thử tail -n+1 /proc/sys/vm/overcommit_*và thêm đầu ra. Xem thêm tại đây: Làm cách nào để định cấu hình oom-killer
kiri

Vì vậy, những gì đang xảy ra với không gian trao đổi của bạn? Bạn có thể đăng một số đầu ra vmstat như #vmstat 1 100 hoặc một cái gì đó tương tự không? và cũng cho chúng tôi thấy cat / etc / fstab Điều gì sẽ xảy ra ở một mức sử dụng bộ nhớ nhất định, bạn nên bắt đầu viết để trao đổi. Quá trình giết chết không nên xảy ra cho đến khi bộ nhớ và không gian trao đổi là "đầy đủ".
j0h

cũng cố gắng #swapon -a
j0h

@ j0h Với trao đổi, nó dường như hoạt động tốt (sau một thời gian quá trình bị lỗi với một cái gì đó như Allocation failed). Nhưng không có trao đổi, nó chỉ đóng băng máy tính. Nó được cho là hoạt động theo cách này (chỉ giết khi sử dụng trao đổi)?
Salem

2
Với SysRq, bạn cũng có thể gọi OOM (SysRq + F iirc)
Lekensteyn

Câu trả lời:


36

Từ tài liệu chính thức/proc/sys/vm/* :

oom_kill_allocating_task

Điều này cho phép hoặc vô hiệu hóa việc hủy tác vụ kích hoạt OOM trong các tình huống hết bộ nhớ.

Nếu điều này được đặt thành 0, kẻ giết người OOM sẽ quét qua toàn bộ danh sách nhiệm vụ và chọn một nhiệm vụ dựa trên phương pháp phỏng đoán để tiêu diệt. Điều này thường chọn một nhiệm vụ ăn cắp bộ nhớ giả mạo giúp giải phóng một lượng lớn bộ nhớ khi bị giết.

Nếu điều này được đặt thành khác không, kẻ giết người OOM chỉ đơn giản là giết chết tác vụ kích hoạt tình trạng hết bộ nhớ. Điều này tránh việc quét danh sách nhiệm vụ đắt tiền.

Nếu panic_on_oom được chọn, nó sẽ được ưu tiên hơn bất kỳ giá trị nào được sử dụng trong oom_kill_allocating_task.

Giá trị mặc định là 0.

Để tóm tắt, khi thiết oom_kill_allocating_taskđể 1, thay vì quét hệ thống của bạn đang tìm kiếm quy trình để giết, đó là một nhiệm vụ tốn kém và chậm, hạt nhân sẽ chỉ giết chết quá trình gây ra hệ thống để có được ra khỏi bộ nhớ.

Từ kinh nghiệm của riêng tôi, khi một OOM được kích hoạt, hạt nhân không còn đủ "sức mạnh" để thực hiện việc quét như vậy, làm cho hệ thống hoàn toàn không thể sử dụng được.

Ngoài ra, sẽ rõ ràng hơn nếu chỉ giết nhiệm vụ gây ra sự cố, vì vậy tôi không hiểu tại sao nó được đặt thành 0mặc định.

Để kiểm tra, bạn chỉ có thể ghi vào tệp giả phù hợp, tệp /proc/sys/vm/này sẽ được hoàn tác trong lần khởi động lại tiếp theo:

echo 1 | sudo tee /proc/sys/vm/oom_kill_allocating_task

Để sửa lỗi vĩnh viễn, hãy viết phần sau vào /etc/sysctl.confhoặc vào một tệp mới bên dưới /etc/sysctl.d/, với .confphần mở rộng ( /etc/sysctl.d/local.confví dụ):

vm.oom_kill_allocating_task = 1

2
Có phải nó luôn được đặt thành 0 trong Ubuntu không? Bởi vì tôi nhớ nó được sử dụng để tự động giết, nhưng vì một vài phiên bản, nó đã ngừng làm như vậy.
skerit

1
@skerit Điều này tôi không thực sự biết, nhưng nó được đặt thành 0 trong các hạt nhân tôi đã sử dụng vào năm 2010 (Debian, Liquorix và GRML).
Teresa e Junior

"Ngoài ra, sẽ rõ ràng hơn nếu chỉ giết nhiệm vụ gây ra sự cố, vì vậy tôi không hiểu tại sao nó được đặt thành 0mặc định." - bởi vì quá trình yêu cầu bộ nhớ không nhất thiết là quá trình "gây ra sự cố". Nếu quá trình A chiếm 99% bộ nhớ của hệ thống, nhưng quá trình B, sử dụng 0,9%, sẽ là nguyên nhân gây ra kẻ giết người OOM bởi sự xui xẻo, B đã không "gây ra vấn đề" và nó không có ý nghĩa gì với kill B. Do chính sách đó có nguy cơ các quá trình bộ nhớ thấp hoàn toàn không có nguyên tắc bị giết một cách tình cờ do sử dụng bộ nhớ chạy trốn của một quá trình khác .
Đánh dấu Amery

1
@MarkAmery Vấn đề thực sự là Linux, thay vì chỉ giết quá trình cần thiết, bắt đầu đập mạnh như một kẻ chậm phát triển, ngay cả khi vm.admin_reserve_kbytesđược tăng lên, giả sử, 128 MB . Cài đặt vm.oom_kill_allocating_task = 1dường như làm giảm bớt vấn đề, không thực sự giải quyết được (và Ubuntu đã xử lý các quả bom ngã ba theo mặc định).
Teresa e Junior

1
Có lẽ thanh lịch hơnsudo sysctl -w vm.oom_kill_allocating_task=1
Pablo A

9

Cập nhật: Lỗi đã được sửa.

Câu trả lời của Teresa là đủ để giải quyết vấn đề và là tốt.

Ngoài ra, tôi đã nộp báo cáo lỗi vì đó chắc chắn là một hành vi bị hỏng.


Tôi không biết lý do tại sao bạn bị hạ cấp, nhưng điều đó cũng có vẻ như là một lỗi kernel đối với tôi. Tôi đã đánh sập một máy chủ đại học lớn ngày hôm nay với nó và giết một số quy trình đang chạy trong nhiều tuần ... Cảm ơn vì đã nộp báo cáo lỗi đó!
shapecatcher

7
Có thể đã được sửa chữa vào năm 2014, vào năm 2018 (và 18.04), kẻ giết người OOM một lần nữa không làm gì cả.
skerit

0

Bạn có thể thử Earlyoom , một kẻ giết người OOM hoạt động trong không gian người dùng và cố gắng giết quá trình lớn nhất trong tình huống OOM.


-1

Trước hết tôi khuyên bạn nên cập nhật lên 13.10 (cài đặt sạch, lưu dữ liệu của bạn).

Nếu bạn không muốn cập nhật, hãy thay đổi vm.swappiness thành 10 và nếu bạn thấy có vấn đề với zRAM cài đặt ram.


2
Tôi không phải là người đánh giá thấp bạn, nhưng nói chung, việc hạ thấp vm.swappinesssẽ gây hại nhiều hơn là tốt, thậm chí nhiều hơn đối với các hệ thống bị các vấn đề bộ nhớ thấp.
Teresa e Junior

Không phải khi bạn nén ram trước và sau đó bạn tránh sử dụng đĩa chậm hơn nhiều và có thể làm cho máy tính của bạn bị đóng băng.
Brask

Về lý thuyết, zRAM là một thứ tốt, nhưng nó đang đói CPU, và nói chung là không đáng giá. Bộ nhớ thường rẻ hơn điện. Và, trên một máy tính xách tay, nơi nâng cấp RAM đắt hơn, việc sử dụng CPU chủ yếu là không mong muốn.
Teresa e Junior

Những gì anh ta yêu cầu là có một hệ thống zRAM ổn định hơn và việc thay đổi swappiness sẽ khiến hệ thống của anh ta sử dụng nhiều tài nguyên CPU hơn, nhưng điều anh ta bị giới hạn và có lỗi với bộ nhớ, anh ta muốn khắc phục vấn đề không phải là một bài học lý thuyết về những gì xảy ra khi bạn cài đặt zRAM.
Brask

Rõ ràng từ câu hỏi của anh ấy rằng anh ấy có thể viết một kịch bản không phù hợp mà ăn nhiều hơn mức cần thiết (và tôi đã tự mình làm điều này). Trong tình huống như thế này, bạn có thể xem tập lệnh lấy hàng gigabyte RAM trong vài giây và zRAM sẽ không đến cứu, vì tập lệnh sẽ không bao giờ đủ thỏa mãn.
Teresa e Junior
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.