Skip to content

Memory Leak: ExcelRangeBase.Copy without ExcelRangeCopyOptionFlags.ExcludeStyles keeps the whole source ExcelPackage in memory indefinitely #2162

@panoskj

Description

@panoskj

EPPlus usage

Noncommercial use

Environment

Windows

Epplus version

8.2.1

Spreadsheet application

Excel

Description

I have a collection of about 100 "source" excel files and I want to create a new "destination" excel file, extracting some data from the source files. This is how I am doing it:

  • Create a single destination ExcelPackage (using the parameterless constructor)
  • Then for each source file, I do the following (one file at a time):
    1. Load the source file using File.ReadAllBytes
    2. Create a MemoryStream from the byte array
    3. Create an ExcelPackage from the stream
    4. Copy a specific range from a specific worksheet using ExcelRangeBase.Copy, essentially appending that range to the end of the destination file
    5. Dispose of the ExcelPackage and the MemoryStream
  • Note that I don't dispose of the destination ExcelPackage until I have run all source files.

This is simple and straightforward to do using EPPlus. However, when I run it, the program keeps increasing memory usage, until it consumes all available RAM. The memory profiler when debugging within Visual Studio shows that the memory is increasing whenever a file is loaded, but it never decreases, not even when a file should have been unloaded. FYI the source files are 0.3-2 MB each in size and EPPlus seems to use a few 100s MB RAM to load each one of them.

The most interesting part is when I enabled ExcelRangeCopyOptionFlags.ExcludeStyles, the memory leak was fixed, without making any other changes. I have the impression named styles may be involved, but I am not sure about that. Unfortunately, I cannot share the source excel files and I am not an excel expert in order to understand if it is something specific to them.

Another workaround I found is saving the destination file (ie to a byte array) after copying a source file to it and then loading it again. This mitigates the memory leak and allows me to preserve styles, but feels suboptimal.

All in all, it looks like when I am copying styles, the destination ExcelPackage somehow keeps a reference to the source ExcelPackage.

PS: I forgot to mention I also tried (for each source file):

  1. Copy from the source ExcelPackage into a temp ExcelPackage
  2. Dispose of source
  3. Try to copy from temp into destination
  4. Dispose of temp

In this case, EPPlus crashes when trying to copy from temp into destination. I think that's where (stacktraces) I might have seen something about named styles that I mentioned earlier and this is what gave me the idea to try serializing/deserializing instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions