Máy chủ bỗng chậm rề, quạt kêu to, hoặc cảnh báo "hết RAM" — và câu hỏi đầu tiên luôn là: tiến trình nào đang gây ra? Đây là kỹ năng chẩn đoán cơ bản nhất mà mọi kỹ sư cần thuộc, và may thay hai công cụ có sẵn khắp nơi trả lời trong vài giây: ps và top. Nhưng biết chạy chúng chưa đủ — phải biết sắp xếp đúng và đọc đúng cột, nếu không bạn nhìn nhầm số và quy tội sai. Bài này (phần 8 loạt Debug) chạy thật hai tiến trình "phá hoại" và truy tìm chúng.
ps aux --sort: xếp hạng tiến trình
ps aux liệt kê mọi tiến trình; thêm --sort để xếp hạng theo tài nguyên (dấu - = giảm dần):
ps aux --sort=-%cpu | head # TOP tiến trình ngốn CPU
ps aux --sort=-%mem | head # TOP tiến trình ngốn RAM
Các cột quan trọng: PID, %CPU, %MEM, RSS (RAM thật), COMMAND. Chỉ cần liếc dòng đầu là thấy thủ phạm.

Hình 1: ps aux --sort=-%cpu/-%mem xếp hạng tiến trình; đọc đúng cột (%CPU có thể >100% đa lõi, RSS là RAM thật); top -b -n1 lấy ảnh chụp cho script; quy trình từ tìm PID tới đào sâu.
Đo thật: truy tìm hai thủ phạm
Mình chạy hai tiến trình: một busy loop ngốn CPU, một giữ ~250MB RAM. Rồi tìm chúng bằng ps sắp xếp hai kiểu:

Hình 2: Chạy thật — --sort=-%cpu: cpuhog.py đứng đầu với 99.5% CPU (RSS chỉ 7MB); --sort=-%mem: ramhog.py đứng đầu với %MEM 3.2, RSS 263240KB (~257MB); top -b -n1 cho cpuhog ở 100.0% CPU.
- Sắp theo
%cpu:cpuhog.pylên đầu với 99.5% CPU nhưng RSS chỉ 7MB — kẻ tính toán nặng, không ngốn RAM. - Sắp theo
%mem:ramhog.pylên đầu với %MEM 3.2, RSS ~257MB nhưng %CPU thấp — kẻ ngốn RAM, không nặng CPU. top -b -n1: chế độ batch (in một lần rồi thoát, thay vì màn hình tương tác) — hữu ích để đưa vào script/log. CộtRES= RSS (RAM thật),%CPU,%MEM. cpuhog hiện 100.0% CPU.
Hai tiến trình, hai kiểu phá hoại khác nhau, và cách sắp xếp đúng đưa đúng thủ phạm lên đầu cho từng vấn đề.
Vì sao %CPU vượt 100%
Điểm hay gây bối rối: %CPU là phần trăm của một lõi, không phải toàn hệ thống. Một tiến trình một luồng chạy full sẽ hiện ~100% (một lõi bận hết). Nhưng tiến trình đa luồng chạy trên nhiều lõi có thể hiện 200%, 400%... — 400% nghĩa là dùng hết 4 lõi. Đây không phải lỗi hiển thị; nó cho biết mức độ song song. Ngược lại, thấy một tiến trình CPU-bound chỉ ở 100% (một lõi) trên máy nhiều lõi = nó không tận dụng đa lõi, có thể là cơ hội tối ưu.
Đánh đổi cần cân nhắc
%CPU của ps là trung bình từ khi tiến trình khởi động, còn top là tức thời. ps tính %CPU = tổng thời gian CPU / thời gian sống của tiến trình — nên một tiến trình từng ngốn CPU nhưng giờ nhàn vẫn có thể hiện %CPU cao trong ps. top (và top -d) đo trong khoảng gần đây, phản ánh hiện tại. Khi cần biết "bây giờ ai đang ngốn", dùng top; khi cần "ai đã ngốn nhiều nhất suốt vòng đời", ps phù hợp hơn.
Sắp xếp cho ảnh chụp, cần theo dõi xu hướng thì lặp lại. Một lần ps/top cho trạng thái lúc đó. Một tiến trình ngốn RAM tăng dần (rò rỉ) khác một tiến trình dùng nhiều RAM ổn định (bình thường) — chỉ thấy được khi theo dõi qua thời gian (top chạy liên tục, hay watch ps ...). Đừng kết luận "rò rỉ" từ một ảnh chụp RSS cao.
Trong container, %CPU/%MEM có thể gây hiểu nhầm. top/ps trong container thường tính phần trăm theo tài nguyên host, không theo giới hạn cgroup của container (như bài cgroups). Một container giới hạn 0.5 lõi có thể hiện %CPU nhỏ so với host dù đã chạm trần của nó. Để đo đúng theo giới hạn container, đọc /sys/fs/cgroup hoặc dùng docker stats (tính theo giới hạn container).
Ba ý mang về
ps aux --sortxếp hạng thủ phạm ngay: đo thật--sort=-%cpuđưacpuhog(99.5% CPU) lên đầu,--sort=-%memđưaramhog(RSS 257MB) lên đầu — sắp đúng theo vấn đề (CPU hay RAM) là thấy đúng kẻ gây.- Đọc đúng cột và hiểu %CPU:
%CPUlà phần trăm một lõi nên có thể >100% trên đa lõi (400% = 4 lõi);RSS/RESlà RAM thật; CPU cao = busy loop, RAM cao/tăng = ngốn/rò rỉ. - Sắp xếp là bước tìm PID, không phải câu trả lời cuối:
pscho trung bình vòng đời,topcho tức thời; theo dõi xu hướng để phân biệt rò rỉ; và trong container dùngdocker statscho đúng giới hạn — có PID rồi thìstrace//proc/time(bài trước) đào sâu vì sao.
Nguồn
- man7.org — ps(1): https://man7.org/linux/man-pages/man1/ps.1.html
- man7.org — top(1): https://man7.org/linux/man-pages/man1/top.1.html
- Brendan Gregg — Linux Performance: https://www.brendangregg.com/linuxperf.html
Phần sau ta đo I/O của một tiến trình: /proc/<pid>/io cho biết nó đọc/ghi bao nhiêu byte thật, và cách tìm tiến trình đang "quật" đĩa khi hệ thống chậm mà CPU vẫn rảnh.