donnytian / Npoi.Mapper

Use this tool to import or export data with Excel file. The tool is a convention based mapper between strong typed object and Excel data via NPOI.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mapper should implements IDispose

houwenlong789 opened this issue · comments

Mapper class Should implements IDispose , and set _workbook = null in Dispose method;
Otherwise it will cause memory leak.

Have you encountered any memory leak when using it?

As I am wondering what should we dispose in a Dispose method:

  • The npoi workbook itself is not disposable, it's a managed resource.
  • Any file steams we created internally are within Using statements. We even close the passed in Stream in one of constructor overloads just like what npoi did, which caused arguments from some guys already.
  • And there is no event handlers to be revoked.

Though implementing IDisposable is always an option no matter whether you are creating any unmanaged resources or not. Below are some of my thoughts:

  • Implementation of IDisposable doesn't make anything more or less "standardized" for managed objects but purely increased the complexity.
  • If you really care about the memory allocation intensively, you can do mapper = null immediately after using of it or even you could use weak reference. But such styles look "old fashioned" as now days languages like C# have evolved to be more focusing on domain business other than infrastructures like garbage collection things.
  • It's also about neatness and concise. Let's don't make developer think that they are creating any unmanaged resources need to be addressed.

What do you think and any test evidence available?

我们应用由于使用下载和上传的人数比较多, 我抓取了一个3g 的Dump, npoi 对象至少占了700M 的内存(不排除是垃圾回收0代就可以回收的). 虽然IWorkbook 没有实现IDispose 方法, 我认为Mapper实现IDispose 方法, 在IDispose方法中 设置IWorkbook 为null 是一个比较好的实践;

Hi,
Set workbook to null does not make the life any better until you call GC.Collect(), which is dangerous and NOT recommended.
To prove this, you can try set mapper = null; after you completed import/ export immediately. This will not help.
Here is blog for this question, and you can check into details, the last 2 sections contain conclusion.
Some suggestions for your issue:

  1. If you created many large objects in the same scope, try refactor them into different methods so that they will be eligible for GC collection immediately after the method call.
  2. Set mapper.TrackObjects = false if you don't need this feature.
  3. Try post you code or example project for help if the issue still exist.

Happy Teacher's Day

My senario like this, first load mass of data from excel. then operate it on memory which it may take some time. So set mapper = null, npoi object will be collected on next garbige collection.
Thanks awesome work!!

As I said, set mapper = null doesn't help here, so you'd better to refine your loading process, try to load partial of data. And this is not a memory leak!

I am closing this issue since so far there is no point to implement IDisposable.
Feel free to re-open this if you want further discussion or got real memory leak case.

Hi @donnytian,

let me reopen this issue.

Since 2018 there is an override in NPOI library which allows leaving stream open: tonyqus/npoi@14604f8

Could you please add this possibility to Npoi.Mapper?