ulimit -n # 查看限制,預設 1024 ulimit -n 4096 # 臨時調大(重啟失效)
為何不可取?
「若程式設計正確,通常無需保持大量 fd 開啟——即使有數千並發連線。調大限制只會延遲問題爆發,無法修復洩漏。」
| 目的 | 指令 | 說明 |
|---|---|---|
| 查進程 PID | pidof java | 或 ps -ef | grep java |
| 查進程開啟的 fd | lsof -p <PID> | 標準方式 |
| 統計 fd 數量 | lsof -p <PID> | grep -v mem | wc -l | 排除 memory-mapped .so 檔案 |
| 更準確統計 | ls -l /proc/<PID>/fd | wc -l | /proc 直接反映內核 fd 表 |
| 查用戶級 fd | lsof -u <user> | grep -v mem | wc -l | 注意:限制是 per-process,非 per-user |
| 內核級統計 | sysctl fs.file-nr | 三值:已分配、未使用但已分配、系統級上限 |
| 系統級上限 | sysctl fs.file-max | 內核支援的最大 fd 總數 |
| 現象 | 原因 | 正確理解 |
|---|---|---|
lsof -u root | wc -l > ulimit -n | 以為用戶級超限 | ulimit 是 per-process 限制,非 per-user。root 下多個進程各自受限 |
lsof -p PID 數 ≠ ls /proc/PID/fd 數 | 統計不一致 | lsof 包含 memory-mapped .so,非進程可控 fd。/proc 更準確 |
# /etc/sysctl.conf fs.file-max = 65536 # 生效 sysctl -p /etc/sysctl.conf
# /etc/security/limits.conf * soft nofile 4096 * hard nofile 8192 # 或指定用戶 nuxeo soft nofile 4096 nuxeo hard nofile 8192 # /etc/pam.d/su 取消註釋 session required pam_limits.so # 重新登入生效
ls /proc/<PID>/fd | wc -l 隨時間增長lsof -p <PID> | awk '{print $5}' | sort | uniq -c | sort -nr 統計 fd 類型分佈close() 是否歸還而非關閉response.close()、連線池配置lsof -u user 判斷是否超限,要看 /proc/<PID>/fdFileInputStream/Socket/Connection 必須在 finally 或 try-with-resources 中關閉「Too many open files」本質是資源管理缺陷,而非配置不足。守住 try-with-resources、連線池參數、異常路徑清理三道防線,才是根治之道。