Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 966616) +++ lucene/CHANGES.txt (working copy) @@ -241,6 +241,9 @@ explicitly enable the old behavior with setAutoGeneratePhraseQueries(true) (Robert Muir) +* LUCENE-2537: FSDirectory.copy() implementation was unsafe and could result in + OOM if a large file was copied. (Shai Erera) + New features * LUCENE-2128: Parallelized fetching document frequencies during weight Index: lucene/src/java/org/apache/lucene/store/FSDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/FSDirectory.java (revision 966616) +++ lucene/src/java/org/apache/lucene/store/FSDirectory.java (working copy) @@ -441,7 +441,20 @@ try { input = new FileInputStream(new File(directory, src)).getChannel(); output = new FileOutputStream(new File(target.directory, dest)).getChannel(); - output.transferFrom(input, 0, input.size()); + /* + * If transferFrom is used without a limit when copying a very large + * file, then an OOM may be thrown (depends on the state of the RAM in + * the machine, as well as the OS used). Performance measurements showed + * that chunk sizes larger than 2MB do not result in much faster file + * copy, therefore we limit the size to be safe with different file + * sizes and systems. + */ + long chunkSize = 1 << 21; // Use 2MB chunk size + long numWritten = 0; + long numToWrite = input.size(); + while (numWritten < numToWrite) { + numWritten += output.transferFrom(input, numWritten, chunkSize); + } } catch (IOException ioe) { priorException = ioe; } finally {