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 inStream
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:
- 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.
- Set
mapper.TrackObjects = false
if you don't need this feature. - 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?