0

JNetPcap ライブラリを使用してパケット スニファを作成しました。これは、システム リソース (RAM、ディスクの使用状況、アクティブなネットワーク インターフェイス、実行中のプロセスなど) を監視する別のアプリケーションから実行される .jar です。モニターアプリケーションが終了したときに(ユーザーによるかどうかに関係なく)スニファーを閉じたいので、モニターアプリでファイルを作成し、fileLockを使用してロックすることを考えました。次に、スニファーのすべてのループで、ファイルがまだロックされているかどうかを確認し、ロックされていない場合 (モニター アプリが終了したことを意味します)、System.exit(0); を呼び出します。

問題は、非ページ カーネル メモリの使用量 (実際には、非ページ カーネル メモリだけではありません) が、両方を実行しているときに急速に増加することです。個別に実行すると発生しません。

それらを同時に実行しても発生しませんが、スニファーアプリの次のコードがコメントされています(モニターによって作成されたファイルがまだロックされているかどうかを確認する責任があります)

        private void checkReleasedLock() throws IOException{
            File file = new File("config\\file.lock");
            FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
            FileLock lock = null;

            try {
                 lock = channel.tryLock();

                 if(lock != null){ //It acquired the lock => the other application is terminated.
                     System.exit(0);
                 } else {
                     file = null;
                     channel = null;
                     lock = null;
                 }
            } catch (Exception e) {
                file = null;
                channel = null;
                lock = null;
            }
        }

メモリ使用量の増加を示すために、これはシステム リソースをログに記録する監視アプリの出力です。

######################################
# Beginning log: 2012-08-03 10:14:26 #
######################################
__________
RAM USAGE:

Total: 2040 MB
Free: 1260 MB (63.31 %)
Used: 720 MB (36.69 %)

Swap total: 4125 MB
Swap used: 1104 MB
Swap free: 3021 MB

Kernel Memory Total: 75876 KB
Paged: 52536 KB
Nonpaged: 23340 KB

そして数時間後…

######################################
# Beginning log: 2012-08-03 12:14:27 #
######################################
__________
RAM USAGE:

Total: 2040 MB
Free: 1000 MB (50.37 %)
Used: 980 MB (49.63 %)

Swap total: 4125 MB
Swap used: 1307 MB
Swap free: 2818 MB

Kernel Memory Total: 213724 KB
Paged: 173724 KB
Nonpaged: 40000 KB

そのコードに何か問題がありますか?メモリリークの原因でしょうか?

4

1 に答える 1

2

そのコードに何か問題がありますか?

そのメソッドを呼び出すたびに、閉じられていない FileChanel オブジェクトが作成されるようです。割り当てnullによって何も閉じられることはありません。

FileChanel が常に閉じていることを確認するには、次のようにコーディングする必要があります。

   private void checkReleasedLock() throws IOException {
        File file = new File("config\\file.lock");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
        FileLock lock;

        try {
            lock = channel.tryLock();
            if (lock != null) {
                System.exit(0);
            }
        } finally {
            channel.close();
        }
    }

すべての例外が押しつぶされるバグも修正したことに注意してください。

メモリリークの原因でしょうか?

はい、そうかもしれません。元の形式のコードでは、開いているファイル チャネルは、オブジェクトが Java ガベージ コレクターによってファイナライズされたときにのみ閉じられます。それまでは、それぞれがオペレーティング システムのリソースを拘束するため、ページ化されていないカーネル メモリの使用量が増加していることが十分に説明できます。

于 2012-08-16T12:17:29.383 に答える