首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Linux "Too many open files" 根因分析與解決方案

     編輯:Java 綜合教學

核心概念

  • 文件描述符:Linux 一切皆文件,進程通過 fd(非負整數)訪問文件、網絡連線、設備等資源
  • lsof:List Open Files,排查資源佔用的核心工具,需 root 權限

錯誤認知:盲目調大 ulimit 是碰運氣

ulimit -n          # 查看限制,預設 1024
ulimit -n 4096     # 臨時調大(重啟失效)

為何不可取?

「若程式設計正確,通常無需保持大量 fd 開啟——即使有數千並發連線。調大限制只會延遲問題爆發,無法修復洩漏。」

  • OS 預設 1024 已經過慎重考慮
  • Apache 等成熟軟體若需更大會明確要求
  • 真兇幾乎總是 文件描述符洩漏:打開後未關閉

洩漏來源不只是文件

  • Socket 連線
  • Pipe 管道
  • 資料庫連線
  • Windows HANDLE
  • 常規文件

系統級排查指令

目的指令說明
查進程 PIDpidof java或 ps -ef | grep java
查進程開啟的 fdlsof -p <PID>標準方式
統計 fd 數量lsof -p <PID> | grep -v mem | wc -l排除 memory-mapped .so 檔案
更準確統計ls -l /proc/<PID>/fd | wc -l/proc 直接反映內核 fd 表
查用戶級 fdlsof -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

# 重新登入生效

排查流程總結

  1. 確認洩漏:監控 ls /proc/<PID>/fd | wc -l 隨時間增長
  2. 定位類型:lsof -p <PID> | awk '{print $5}' | sort | uniq -c | sort -nr 統計 fd 類型分佈
  3. 代碼審查:重點檢查
    • 資料庫連線池:close() 是否歸還而非關閉
    • HTTP 客戶端:response.close()、連線池配置
    • 文件流:try-with-resources 確保關閉
    • Socket:超時、異常路徑是否關閉
  4. 驗證修復:壓測觀察 fd 曲線平穩

避坑指南

  • 不要用 lsof -u user 判斷是否超限,要看 /proc/<PID>/fd
  • 不要以調大 ulimit 替代修復洩漏
  • Java 中 FileInputStream/Socket/Connection 必須在 finally 或 try-with-resources 中關閉
  • 連線池「關閉」通常是歸還池中,非真關閉底層 fd,池大小限制才是關鍵

「Too many open files」本質是資源管理缺陷,而非配置不足。守住 try-with-resources、連線池參數、異常路徑清理三道防線,才是根治之道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved