- JAVA
Too many open filesの原因と直し方|Java
Too many open files は、1つのプロセスが同時に開けるファイル(ファイル記述子)の上限に達したときのエラーです。 Java では、ファイルや通信を開いたまま閉じていない(リーク)ことが一番の原因です。
| 例外 | 出た場面(確認環境) |
|---|---|
java.io.FileNotFoundException: f61.txt (Too many open files) |
new FileReader(...) |
java.nio.file.FileSystemException: f61.txt: Too many open files |
Files.newBufferedReader(...)・Files.lines(...) |
FileNotFoundException と表示されても、ファイルが無いわけではありません。 括弧の中の Too many open files が本当の原因です。
| 直し方 | 内容 |
|---|---|
| ① 閉じ忘れを直す(根本) | try-with-resources で必ず閉じる。Files.lines も閉じる |
| ② 開いている数を数えて、増え続けていないか確かめる | Linux は ls /proc/PID/fd | wc -l |
| ③ 上限を確かめる・上げる | ulimit -n、/proc/PID/limits。閉じ忘れがあると、上げても時間の問題 |
確認環境:OpenJDK 21(Linux)。ulimit -n 64 で上限を下げ、200個のファイルを順に読むプログラムで再現しました(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Too many open filesの原因と直し方|Java」
再現:閉じ忘れると、上限で止まる
for (int i = 1; i <= 200; i++) {
BufferedReader r = new BufferedReader(new FileReader("f" + i + ".txt"));
r.readLine(); // close していない
}
| 読み方(200ファイル、上限 64) | 結果 |
|---|---|
new FileReader を閉じない |
60 ファイルで停止(FileNotFoundException: f61.txt (Too many open files)) |
Files.newBufferedReader(p).readLine()(閉じない) |
60 ファイルで停止(FileSystemException) |
Files.lines(p).count()(閉じない) |
60 ファイルで停止 |
try (BufferedReader r = ...) |
200 ファイルすべて成功。開いている数は 5 のまま |
try (Stream<String> s = Files.lines(p)) |
200 ファイルすべて成功 |
上限 64 のうち、JVM 自身が使う分があるため、60 ファイルで止まりました。 閉じ忘れたファイルは、プログラムが動き続ける限り開いたまま残ります。
Files.lines も閉じる必要がある
long n = Files.lines(p).count(); // ← 閉じ忘れ
try (Stream<String> s = Files.lines(p)) { // ← 正しい
long n = s.count();
}
Files.lines の Stream は、最後まで読んでも自動では閉じませんでした。 Java の公式ドキュメント(Stream)でも、ほとんどの Stream は閉じる必要がないが、Files.lines のように IO が元の Stream は閉じる必要があり、try-with-resources で開くと説明されています。確認環境では、Files.list(...).count()・Files.walk(...).count() も、閉じないと同じ上限で止まりました。
直し方:try-with-resources
try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
String line = r.readLine();
} // ここで必ず close される(例外が起きても)
Java の公式チュートリアルでは、try-with-resources は、宣言した資源を文の終わりで必ず閉じると説明されています。finally で close() を書くより、書き忘れ・例外の取りこぼしが起きにくい書き方です。詳しくは既存の記事「Java try-with-resourcesの使い方|finallyとの違い」で扱っています。
| 閉じる必要があるもの | 例 |
|---|---|
| ファイル | FileReader・FileInputStream・Files.newBufferedReader |
| IO が元の Stream | Files.lines・Files.list・Files.walk |
| DB | Connection・Statement・ResultSet |
| 通信 | Socket、HTTP の応答の本文(InputStream) |
ファイルだけでなく、通信の接続も同じ上限を使います。 DB の接続を返し忘れる、HTTP の応答を読み切らずに捨てる、といった形でも同じエラーになることがあります。
開いている数を数える(Linux)
閉じ忘れのあるプログラムで 50 ファイルを開いたまま止め、外から数えました。
jps # Java のプロセスの PID を調べる
ls /proc/7827/fd | wc -l # 54
ls -l /proc/7827/fd | grep -c '\.txt' # 50
grep "open files" /proc/7827/limits # Max open files 20000 20000 files
10 -> /srv/s4/j10/e5/f7.txt
11 -> /srv/s4/j10/e5/f8.txt
/proc/PID/fd には、開いているファイルの一覧があり、どのファイルを開いたままかまで分かりました。 同じファイル名・同じ種類のファイルがたくさん並んでいたら、その処理が閉じ忘れています。時間をおいて何度か数え、増え続けていればリークです。
| 確かめること | 方法 |
|---|---|
| 今開いている数 | ls /proc/PID/fd | wc -l |
| 何を開いているか | ls -l /proc/PID/fd |
| 上限 | /proc/PID/limits の Max open files |
| シェルの上限 | ulimit -n |
上限を上げる前に
上限を上げると、エラーが出るまでの時間は延びますが、閉じ忘れがあれば、いずれまた止まります。 先に、開いている数が増え続けていないかを確かめます。
| 状況 | 判断 |
|---|---|
| 数が増え続ける | 閉じ忘れ(リーク)。コードを直す |
| 数が一定だが、上限に近い | 同時に扱うファイル・接続が多い。上限を見直す |
プログラムをサービスとして起動している場合、上限は起動の設定によって決まり、ログインしたシェルの ulimit -n とは違うことがあります。 動いているプロセスの /proc/PID/limits で、実際の値を確かめます。
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | 例外の括弧の中 | (Too many open files) なら上限の問題 |
| 2 | 開いている数が増え続けるか | ls /proc/PID/fd | wc -l を何度か |
| 3 | 何を開いたままか | ls -l /proc/PID/fd |
| 4 | 閉じ忘れのコード | new FileReader・Files.lines・接続を try-with-resources に |
| 5 | 実際の上限 | /proc/PID/limits |
よくある質問
Q. GC(ガベージコレクション)が動けば、閉じ忘れたファイルも閉じられますか。 A. 当てにできません。確認環境でも、閉じ忘れたまま 60 ファイルで止まりました。開いたものは、使い終わったらすぐに閉じるのが原則です。
まとめ
- 同時に開けるファイル(ファイル記述子)の上限に達したエラー
- 原因の多くは閉じ忘れ。
FileNotFoundException (Too many open files)と表示されることも Files.lines・Files.list・Files.walkも閉じる必要がある- try-with-resources で、例外が起きても必ず閉じる
/proc/PID/fdの数が増え続けるならリーク。上限を上げるのはその後
参考・出典
確認日はいずれも 2026年10月11日です。
- Java SE 21 API「Stream」(IO が元の Stream は閉じる必要がある):https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Stream.html
- The Java Tutorials「The try-with-resources Statement」:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Too many open filesの原因と直し方|Java」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。