Bất kỳ vấn đề nếu trạng thái Zombie không được xóa?


18

Tôi có đơn vị sản xuất trong đó quá trình java đã trở thành Zombie và vẫn ở đó một thời gian. Nếu thiết bị được khởi động lại, nó sẽ bị xóa. Tuy nhiên, đơn vị không được khởi động lại và một quá trình java khác đang hoạt động. Có vấn đề gì nếu trạng thái zombie này vẫn như cũ mà không xóa nó? Nó sẽ ảnh hưởng theo bất kỳ cách nào (hiệu suất hoặc chậm)?

Câu trả lời:


22

Quá trình Zombie sẽ không có bất kỳ ảnh hưởng nào đến hiệu suất hoặc sự chậm chạp vì quá trình Zombie không sử dụng bất kỳ tài nguyên hệ thống nào.

Lưu ý: - Thực tế, nó vẫn đang sử dụng PID (vốn là tài nguyên giới hạn) và cấu trúc dữ liệu kernel cho quy trình vẫn được phân bổ. Thông thường, điều này sẽ không quan trọng lắm, nhưng việc sử dụng bộ nhớ kernel có thể có ý nghĩa đối với các hệ thống có bộ nhớ rất hạn chế.

Vấn đề gây ra bởi quá trình zombie

Mỗi quá trình zombie giữ lại ID tiến trình của nó. Các hệ thống Linux có số lượng ID quy trình hữu hạn - 32767 theo mặc định trên các hệ thống 32 bit. Nếu zombie được tích lũy với tốc độ rất nhanh, toàn bộ nhóm các PID có sẵn cuối cùng sẽ được gán cho các quy trình zombie, ngăn các quá trình khác khởi chạy.

Lưu ý : Trên các hệ thống 64 bit, bạn có thể tăng mức tối đa PID, xem /unix//a/16884/170373

Tuy nhiên, một vài quy trình zombie treo xung quanh không có vấn đề gì - mặc dù chúng chỉ ra lỗi với quy trình cha mẹ của chúng trên hệ thống của bạn.

Giải trình:

Khi một tiến trình chết trên Linux, nó không bị xóa khỏi bộ nhớ ngay lập tức - bộ mô tả quy trình của nó vẫn nằm trong bộ nhớ.

Trạng thái của quá trình trở thành EXIT_ZOMBIEvà cha mẹ của quá trình được thông báo rằng tiến trình con của nó đã chết với SIGCHLDtín hiệu.

Quá trình cha sau đó được cho là thực hiện lệnh gọi hệ thống Wait () để đọc trạng thái thoát của tiến trình chết và các thông tin khác. Điều này cho phép tiến trình cha mẹ lấy thông tin từ tiến trình chết. Sau khi Wait () được gọi, quá trình zombie hoàn toàn bị xóa khỏi bộ nhớ.

Điều này thường xảy ra rất nhanh, vì vậy bạn sẽ không thấy các quá trình zombie tích lũy trên hệ thống của mình. Tuy nhiên, nếu một quy trình cha mẹ không được lập trình đúng và không bao giờ gọi chờ (), những đứa trẻ zombie của nó sẽ lưu lại trong bộ nhớ cho đến khi chúng được dọn sạch.

Nghị quyết:

Bạn không thể tiêu diệt các quy trình zombie vì bạn có thể tiêu diệt các quy trình thông thường bằng tín hiệu SIGKILL - các quy trình zombie đã chết.

Một cách để tiêu diệt zombie là gửi tín hiệu SIGCHLD đến tiến trình cha. Tín hiệu này cho biết quá trình cha mẹ thực hiện lệnh gọi hệ thống Wait () và dọn sạch các zombie con của nó. Gửi tín hiệu bằng lệnh kill, thay thế pid trong lệnh bên dưới bằng PID của tiến trình cha:

kill -s SIGCHLD pid

Khi quá trình tạo ra zombie kết thúc, init sẽ thừa hưởng các quá trình zombie và trở thành cha mẹ mới của chúng. (init là quá trình đầu tiên được khởi động trên Linux khi khởi động và được gán PID 1.)

Lưu ý: - Từ Linux 3.4 trở đi, các quy trình có thể thực hiện lệnh gọi hệ thống prctl () với tùy chọn PR_SET_CHILD_SUBREAPER và kết quả là chúng, chứ không phải xử lý # 1, sẽ trở thành cha mẹ của các quá trình hậu duệ mồ côi của chúng. Tham khảo: /unix//a/177361/5132  

INIT sau đó thực hiện lệnh gọi hệ thống Wait () để dọn sạch lũ zombie của nó, do đó init sẽ tạo ra các tác phẩm ngắn của zombie. Bạn có thể khởi động lại quá trình cha sau khi đóng nó.


Có bất kỳ cơ hội mà chờ đợi () chính nó thất bại?
Ravi

3
Trên các hệ thống 64 bit, bạn có thể tăng mức tối đa PID, xem unix.stackexchange.com/a/16884/170373
ilkkachu

1
Phần về việc hối lỗi cũng sai. unix.stackexchange.com/a/177361/5132 Trớ trêu thay, làm cho các chương trình con không mong đợi là một cách dễ dàng để gây ra các quá trình zombie dài hạn.
JdeBP

2
Phụ huynh sẽ nhận được một SIGCHLD khi quá trình bây giờ là một thây ma chết.
Ángel

2
Nói đúng ra là không đúng khi nói rằng nó không sử dụng tài nguyên. Nó vẫn đang sử dụng PID (vốn là tài nguyên giới hạn) và cấu trúc dữ liệu kernel cho quy trình vẫn được phân bổ. Thông thường, điều này sẽ không quan trọng lắm, nhưng việc sử dụng bộ nhớ kernel có thể có ý nghĩa đối với các hệ thống có bộ nhớ rất hạn chế.
Austin Hemmelgarn

6

Hầu hết, zombie không phải là một vấn đề lớn. Chúng là một quá trình 'chết', không mất thời gian của CPU và bất kỳ bộ nhớ được phân bổ nào cũng phải được giải phóng bởi quy trình trước khi chết. Tài nguyên duy nhất họ thực sự lấy là một mục trong danh sách quy trình của bạn. Tùy thuộc vào hệ thống của bạn, bạn có thể có số lượng chủ đề tối đa được phép và việc có zombie có thể khiến bạn đạt đến giới hạn này nhanh hơn mà không có lý do.

Tuy nhiên: Zombie thường xuất hiện do mã xấu / lỗi, trong đó lập trình viên quên kiểm tra trạng thái của các tiến trình con của nó. Điều này có thể có chủ ý, nhưng thường thì không. Mã xấu / lỗi thường cũng sẽ xử lý bộ nhớ theo cách đặc biệt xấuKhông miễn phí một số tài nguyên được phân bổ. Nếu đây là trường hợp, các tài nguyên này sẽ được phân bổ cho zombie, cho đến khi nó bị chấm dứt hoàn toàn.

Chỉnh sửa : Nếu quá trình là một chương trình java, bộ nhớ không được giải phóng sẽ không thành vấn đề, vì trình thu gom rác java sẽ xử lý tất cả mọi thứ.


3
Trong thực tế, không phải bộ nhớ nguồn cấp dữ liệu không phải là vấn đề, hầu hết các hệ điều hành ở tất cả các ngôn ngữ. Hệ thống sẽ giải phóng tất cả bộ nhớ ngoại trừ số lượng nhỏ cho quá trình cha.
val nói phục hồi Monica
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.