2017-02-23 52 views
0

我有一個java服務,下載非常大的文件,做一些處理,然後刪除它們。我注意到服務持有文件描述符直到垃圾收集運行。這是一個問題,因爲操作系統(debian)無法回收該空間,直到文件描述符被釋放。如何強制JVM在文件對象超出範圍後回收該空間?我寧願不使用system.gc()刪除的文件持有文件描述符,直到垃圾收集

要清楚,我已經

  1. 運行lsof,看到被刪除的文件(標記爲deleted)觀察到這種行爲。另外df -h顯示佔用空間的文件。
  2. 正在運行jcmd <pid> GC.run
  3. 正在運行lsof並且不再看到該文件。顯示磁盤空間的df -h

這裏的Java代碼的簡化版本:

public void downloadAndProcess() throws IOException { 
    File destinationFile = new File("blah"); 
    s3Client.getObject(
      new GetObjectRequest(bucket, key), 
      destinationFile 
    ); 
    // do some processing 
    destinationFile.delete(); 
} 
+4

你關閉這些文件嗎?通過手動調用close()或通過使用try-with-resources? –

+0

雖然有些Windows實現的報告通過File保存到GC,但是沒有涉及刪除的文件描述符。 – EJP

+0

如果你不喜歡答案,請評論爲什麼。 JVM垃圾收集器擺脫了無用的文件描述符(只是小整數),但它與鎖定或刪除文件沒有多大關係。 – iantonuk

回答

-1

「這是一個問題,因爲直到文件描述符發佈的OS(Debian的)不能收回空間」

這是你的問題,這是不正確的。文件描述符只是一個整數,每個進程都會得到一個(這取決於進程,而不是os)。操作系統將在這種情況下回收空間,這正是文件描述符的用途(不是指向文件bytearray的指針)。

如果仍然以任何方式出現問題,請發佈您的java代碼和shell代碼,以便明確問題所在。

+0

不,我的操作系統在GC發生之前不會回收空間。如果我發出'sudo df -h /',我看到空間還沒有被釋放。 –

+0

這就是你的答案。閱讀http://askubuntu.com/questions/280342/why-do-df-and-du-commands-show-different-disk-usage#390301 – iantonuk

+0

答案是不完全正確的,因爲它不是文件描述符,它的調用方式不同(文件描述符是一個特定於進程的4個字節的小整數,它不會佔用超過4個字節的內容 - 0x00000003用於第一個打開的文件)。但是這個命令提供了一些不同的東西,你認爲它是。你可以得到這個空間(使用du命令) – iantonuk