[解決済み] ファイルディスクリプタの漏洩例?
質問
Android におけるファイル記述子のリークを実証する良い例はありますか?どこかで読んだのですが、例えば次のようにストリームを閉じないと発生するそうです。
FileInputStream
または
FileOutputStream
しかし、それを実証する良い参考例が見つかりませんでした。
ブログ/コードスニペットを共有してください。
どのように解決するのですか?
なぜなら、Dalvikの ファイルインプットストリーム 意志 ガベージコレクトされたときに自分自身を閉じる (これはOpenJDK/Oracleにも言えることです)実際にファイルディスクリプタをリークすることは思ったより少ないです。もちろん、ファイルディスクリプタはGCが実行されるまでquot;leaked"なので、プログラムによっては再取得されるまでに時間がかかるかもしれません。
より恒久的なリークを実現するには、メモリ上のどこかでストリームへの参照を保持することで、ガベージコレクションされないようにする必要があります。
以下は、1秒ごとにプロパティファイルをロードし、それが変更されるたびに追跡する短い例です。
public class StreamLeak {
/**
* A revision of the properties.
*/
public static class Revision {
final ZonedDateTime time = ZonedDateTime.now();
final PropertiesFile file;
Revision(PropertiesFile file) {
this.file = file;
}
}
/*
* Container for {@link Properties} that implements lazy loading.
*/
public static class PropertiesFile {
private final InputStream stream;
private Properties properties;
PropertiesFile(InputStream stream) {
this.stream = stream;
}
Properties getProperties() {
if(this.properties == null) {
properties = new Properties();
try {
properties.load(stream);
} catch(IOException e) {
e.printStackTrace();
}
}
return properties;
}
@Override
public boolean equals(Object o) {
if(o instanceof PropertiesFile) {
return ((PropertiesFile)o).getProperties().equals(getProperties());
}
return false;
}
}
public static void main(String[] args) throws IOException, InterruptedException {
URL url = new URL(args[0]);
LinkedList<Revision> revisions = new LinkedList<>();
// Loop indefinitely
while(true) {
// Load the file
PropertiesFile pf = new PropertiesFile(url.openStream());
// See if the file has changed
if(revisions.isEmpty() || !revisions.getLast().file.equals(pf)) {
// Store the new revision
revisions.add(new Revision(pf));
System.out.println(url.toString() + " has changed, total revisions: " + revisions.size());
}
Thread.sleep(1000);
}
}
}
レイジーローディングのため InputStream の中で PropertiesFile を作成するたびに保持されます。 リビジョン また、ストリームを閉じることがないため、ここでファイルディスクリプタを漏らすことになります。
さて、これらの開いているファイルディスクリプタは、プログラムが終了するとOSによって閉じられますが、プログラムが実行されている限り、ファイルディスクリプタをリークし続けることが、以下のようにしてわかります。 lsof :
$ lsof | grep pf.properties | head -n 3
java 6938 raniz 48r REG 252,0 0 262694 /tmp/pf.properties
java 6938 raniz 49r REG 252,0 0 262694 /tmp/pf.properties
java 6938 raniz 50r REG 252,0 0 262694 /tmp/pf.properties
$ lsof | grep pf.properties | wc -l
431
そして、強制的にGCを実行させると、これらのほとんどが返されることがわかります。
$ jcmd 6938 GC.run
6938:
Command executed successfully
$ lsof | grep pf.properties | wc -l
2
残りの2つのディスクリプタは リビジョン s.
私はUbuntuマシンでこれを実行しましたが、Androidで実行しても同じような出力になると思います。
関連
-
[解決済み】HTTPステータス500 サーブレットクラスのインスタンス化エラー [重複]。
-
[解決済み】メソッド本体がない、またはJavaで抽象的な宣言をする
-
[解決済み】Gradleがtools.jarを見つけ出さない
-
[解決済み】javaで無効な文字定数
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] ファイルの内容からJavaの文字列を作成するにはどうすればよいですか?
-
[解決済み] ファイルを作成し、書き込むにはどうすればよいですか?
-
[解決済み] performSelectorのセレクタが不明なため、リークが発生する可能性があります。
-
[解決済み] Androidでファイルをダウンロードし、ProgressDialogで進捗を表示する。
-
[解決済み] AsyncTaskのAndroidサンプル
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】popBackStack()とreplace()の操作はどう違うのですか?
-
[解決済み】「error: '.class' expected」の意味と修正方法について
-
[解決済み】Javaで無限大を実装する方法とは?
-
[解決済み] メソッドがそのスーパークラスのメソッドをオーバーライドしない
-
[解決済み】ソースルート外のJavaファイル intelliJ
-
[解決済み】Java Error "Exception in thread "main" java.util.InputMismatchException" Array プログラムで発生。
-
[解決済み] [Solved] java.lang.NoClassDefFoundError: クラスXXXを初期化できませんでした。
-
[解決済み] StringBuilderをクリアまたは空にするにはどうすればよいですか?重複] [重複] [重複] [重複] [重複] [重複
-
[解決済み】フォルダに書き込もうとすると「java.nio.file.AccessDeniedException」が発生する件
-
[解決済み】CreateProcess error=2, The system cannot find file specified.