简体   繁体   中英

Android memory leak when using org.apache.commons.io.FileUtils

I'm trying to copy all the image files on an SD card (connected to a rooted Android device running 4.0.4) to a Hard Drive connected to the same device. I'm new to Android programming so forgive me if the question's answer is obvious.

I use the following method, which is called from the onHandleIntent(Intent intent) of a service, to to the copying:

private void copyImages(File sourceDirectory, File destinationDirectory) throws IOException {
    int count = 0;
    IOFileFilter imageFilter = new ImageFilter();
    IOFileFilter visibleDirectoryFilter = new VisibleDirectoryFilter();

    long startTime = System.nanoTime();
    if (sourceDirectory.exists() && destinationDirectory.exists()) {
        Collection<File> fileList = FileUtils.listFiles(sourceDirectory, imageFilter, visibleDirectoryFilter);
        for (File image : fileList) {               
            FileUtils.copyFileToDirectory(image, destinationDirectory);
            count++;
        }
    }

    long totalTime = System.nanoTime() - startTime;
    Toast.makeText(this, count + " files copied in " + (totalTime) + " nanos.", Toast.LENGTH_LONG).show();
}

However, when I run this, after 36 images are copied, I start continuously getting GC_CONCURRENT freed aK, b% free cK/dK, paused ems+fms where a , b , c , d , e and f are different numbers. I get this non-stop for a long time (as long as I've waited) without any other images being copied.

I understand (I think I do anyway) that this is because the heap is full and Dalvik is trying to free up memory. But, I'm not sure how I can stop this from happening, the program should be able to copy many more (possibly thousands) images. Perhaps the apache commons FileUtils class is too heavy for Android in which case is there another Android-friendly library for neat file handling or must I write my own simple one? Or maybe I'm going wrong elsewhere.

Any help is much appreciated.

Thanks in advance.

This is a non-issue most likely. GC is a normal part of the application processing. In fact, I'd bet if your app is busy doing slow IO, the system has decided now is a good time to do some cleaning up.

The source for FileUtils is open, of course. Its not particularly scary:

http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/FileUtils.java#FileUtils.doCopyFile%28java.io.File%2Cjava.io.File%2Cboolean%29

The only thing arguably "bloaty" is creating the copy buffer. Default is 4K: http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/IOUtils.java#IOUtils.copyLarge%28java.io.InputStream%2Cjava.io.OutputStream%29

I would not get too worried about this, unless you can isolate real issues to that code.

From a performance perspective, you may want to test if BufferedInputStream/OutputStream offer any advantage here. Questionable, as the IOUtils copy method is using a buffer as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM