1

しばらく前に、以下のコードについて助けを求めていましたが、ついに再び作業を開始しました。基本的に、エラーをこのエラーの原因となっているファイルのサイズに絞り込みました。

スレッド「メイン」の例外 java.lang.OutOfMemoryError: Java ヒープ領域

スタック トレースのそのエラーのすぐ下の行は次のとおりです。 at java.util.Arrays.copyOf(Arrays.java:2786)

このプログラムに何千もの小さなファイルを含む大きなディレクトリを渡すことができますが、この 50 MB を超えるサイズのファイルはクラッシュする傾向があります。プログラムがクラッシュする正確なサイズは追跡していませんが、少なくとも 50 Mb のファイルで問題が発生することはわかっています。

以下は主なスニペットで、スタック トレースでコードが壊れていることがわかります。

private void handleFile(File source)
{
    FileInputStream fis = null;

    try
    {
        if(source.isFile())
        {
            fis = new FileInputStream(source);
            handleFile(source.getAbsolutePath(), fis);
        }
        else if(source.isDirectory())
        {
            for(File file:source.listFiles())
            {
               if(file.isFile())
               {
                   fis = new FileInputStream(file);
                   handleFile(file, fis);
               }
               else
               {
                   handleFile(file);
               }
            }
         }
     }
     catch(IOException ioe)
     {
         ioe.printStackTrace();
     }
     finally
     {
         try
         {
             if(fis != null) { fis.close(); }
         }
         catch(IOException ioe) { ioe.printStackTrace(); }
     }
}

private handleFile(String fileName, InputStream inputStream)
{
    byte[] startingBytes = null;

    try
    {
       startingBytes = inputStreamToByteArray(inputStream);

       if(startingBytes.length == 0) return;

       if(isBytesTypeB(startingBytes))
       {
          do stuff
          return;
       }
     }
     catch(IOException ioe)
     {
         ioe.printStackTrace();
     }
}

private byte[] inputStreamToByteArray(InputStream inputStream)
{
    BufferedInputStream bis = null;
    ByteArrayOutputStream baos = null;

    try
    {
        bis = new BufferedInputStream(inputStream);
        baos = new ByteArrayOutputStream(bis);

        byte[] buffer = new byte[1024];

        int nRead;
        while((nRead = bis.read(buffer)) != -1)
        {
            baos.write(buffer, 0, nRead);
        }
    }
    finally { baos.close(); }

    return baos.toByteArray();
 }

 private boolean isBytesTypeB(byte[] fileBytes)
 {
     // Checks if these bytes match a particular type
     if(BytesMatcher.matches(fileBytes, fileBytes.length))
     {
         return true;
     }
     return false;
 }

したがって、上記のコードにはエラーの原因となっているものがあります。ここで私が間違っていることはありますか?

4

3 に答える 3

2

Arrays.copyOfByteArrayOutputStreamの内部配列のサイズ変更が必要になるたびに呼び出されます。これは、メモリ要求が最も高くなる瞬間です。ファイル サイズと等しい配列の初期サイズを指定することで、配列のサイズ変更を回避できます。

于 2013-05-08T17:38:45.607 に答える
1

すべてのコードを読んだわけではありませんが、利用可能なヒープ領域を増やして Java を起動することは可能です

java -Xmx128m

例えば。

于 2013-05-08T17:38:04.280 に答える