質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

解決済

1回答

6208閲覧

子プロセスの実行完了後、ストリームオブジェクトのclose処理を実行しなくても、ファイルディスクリプタは解放されるのか

curveworks

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

0クリップ

投稿2018/06/28 03:40

知りたいこと

某システムのJavaサーブレット側の既存処理で、
サブプロセス(chmodコマンド)を実行し、その結果をログに出力、という処理があるのですが、
処理中に利用しているInputStream、BufferedReaderオブジェクトのcloseが行われていません。
そのため、処理を実行するたびにファイルディスクリプタが増加してしまうと思うのですが、
現状、問題は発生していません。
ファイルディスクリプタはサブプロセス実行後に解放されているのでしょうか?
ご回答のほどよろしくお願い致します。

該当のソースコード

Java

1//属性変更のコマンド 2String processCommand = "chmod 666 " + ファイル名 + " 2>&1 ; echo $? "; 3 4try{ 5 // コマンド実行 6 Process process = Runtime.getRuntime().exec(processCommand); 7 process.waitFor(); 8 9 // ストリームを取得 10 InputStream inputStream = process.getInputStream(); 11 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 12 13 StringBuffer outBuf = new StringBuffer(); 14 while (reader.ready()) { 15 String line = reader.readLine(); 16 outBuf.append(line + " "); 17 } 18 // ログ出力 19 logger.debug("ファイル属性変更結果:" + ファイル名 + " " + outBuf.toString()); 20 21} catch (InterruptedException e) { 22 logger.debug("ファイル属性変更失敗:" + e.getMessage()); 23} catch (IOException ex){ 24 logger.debug("ファイル属性変更失敗:" + e.getMessage()); 25} catch (Exception ex){ 26 logger.debug("ファイル属性変更失敗:" + e.getMessage()); 27} finally { 28 ; 29}

試したこと

■ファイルディスクリプタの増加を検証
<コマンド>
ls /proc/実行しているTomcatのプロセスID/fd | wc -l
<結果>
プログラム実行前:209
プログラム実行完了直後:211      →[socket:xxxx]というファイルディスクリプタが2件増加
プログラム実行完了から数秒経過後:209 →増えた[socket:xxxx]という2件が減少。プログラム実行前と同じ状態

その他気になっていること

process.getInputStream()では標準入出力ストリーム、標準エラー出力ストリームから渡される、とJavadocに記載があるので、
ファイルディスクリプタ#0、#1、#2は標準で使用されているから、そもそも閉じなくてはいいのでは?と思ったが、
ネットで調べると、3つのストリームは使用するしないに関わらずcloseしてくださいとあるので、
自分のファイルディスクリプタに対する認識が誤っていそうな。。

補足情報(FW/ツールのバージョンなど)

OS: Red Hat Enterprise Linux Server release 6.5
JRE: 1.7.0_45
JVMの再起動は年に数回程度のため、JVM再起動によるファイルディスクリプタの解放は考えにくいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

<検証>
プログラムに該当処理の前後にThread.sleep()を入れ、sleep中に該当プロセスにおけるファイルディスクリプタを変動を確認する。

<検証手順>
1.ソースにThreep.sleep()(とログ出力)を追加

Java

1//属性変更のコマンド 2String processCommand = "chmod 666 " + ファイル名 + " 2>&1 ; echo $? "; 3 4try{ 5 // コマンド実行 6 Thread.sleep(60000); 7 logger.info("コマンド実行前"); 8 Process process = Runtime.getRuntime().exec(processCommand); 9 Thread.sleep(60000); 10 logger.info("コマンド実行後"); 11 process.waitFor(); 12 13 // ストリームを取得 14 Thread.sleep(60000); 15 logger.info("process.getInputStream実行前"); 16 InputStream inputStream = process.getInputStream(); 17 Thread.sleep(60000); 18 logger.info("process.getInputStream実行後"); 19 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 20 Thread.sleep(60000); 21 logger.info("BufferedReader実行後");

2.該当プロセスの確認
今回はTomcat上で動いているプロセスのため、

ps -ef | grep tomcat

でプロセスIDを取得。

3.プログラムの実行

4.ファイルディスクリプタの確認
sleep処理実行中、linuxにて

ls -ltr /proc/プロセスID/fd

を実行し、sleepを入れいているタイミングごとの変更を確認。

5.すべてのsleep時に確認した「4.」の実行結果を比較し、ファイルディスクリプタの変遷を確認。

<結果確認>
ファイルディスクリプタの増加は確認できなかった。以下が考えられる。

  • ファイルディスクリプタは作成されない
  • ファイルディスクリプタは作成されたが、chmodの処理完了後、即解放されている

投稿2018/07/10 08:01

curveworks

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問