CLR and Garbage Collection

Started by stanl, June 18, 2013, 12:33:50 PM

Previous topic - Next topic

stanl

I am working on a WB script using the CLR to convert a slew of .xls files to .xlsx [I realize this can be done w/out the CLR].
I am running the conversion through PS code and the ComObject. It is recommended that the PS code end with
[gc]::collect()
[gc]::WaitForPendingFinalizers()


as it was noted the CLR often does not release COM objects. 

But regardless if I use PS or just straight WB code is the garbage collection something I might want to avoid?

Deana

Quote from: stanl on June 18, 2013, 12:33:50 PM
I am working on a WB script using the CLR to convert a slew of .xls files to .xlsx [I realize this can be done w/out the CLR].
I am running the conversion through PS code and the ComObject. It is recommended that the PS code end with
[gc]::collect()
[gc]::WaitForPendingFinalizers()


as it was noted the CLR often does not release COM objects. 

But regardless if I use PS or just straight WB code is the garbage collection something I might want to avoid?

As I understand it. The doNet functions in WinBatch handle the garbage collection on your behalf. However any COM automation objects are your responsibility to free/close.
Deana F.
Technical Support
Wilson WindowWare Inc.

stanl

Thanks. Just in case

;Winbatch 2013 - CLR Garbage Collection Object
;
;
;Stan Littlefield June 18, 2013
;////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectClrOption("use","System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
oGC = ObjectClrNew('System.GC')
;just testing 1 property and 2 methods
maxgen = oGC.MaxGeneration
Message("",maxgen)
oBool = ObjectType("BOOL",0)
oGC.Collect(0)
Message("",oGC.GetTotalMemory(oBool))
oGC=0
Exit
;//////////////////////////////////////////////////////////////////////


td

The general advice in the dotNet world is to let the CLR garbage collector do it its thing and not mess with it.  Under certain conditions forcing collection can actual reduce CLR performance or in a worst case scenario, cause a deadlock.

I have witnessed cases where a WIL script will create new instances of a FCL class many times over and the CLR will figure this out and start reusing the same memory for the class instance after a few iterations. This indicates that CLR GC is fairly sophisticated in its approach to its task.

On the other side of the issue is the WBS debugger. Since it runs scripts in a separate thread of the main WBS process, the garbage collector is not going to necessarily destroy objects between script runs during a debugging session.  This means that performance might be impacted over time.   This situation might be analogous to the situation your PS cohorts are fussing about because the PS process remains between PS script runs.  However, since this only occurs in a debugging situation for WIL scripts, performance is not the top priority anyway and I have never seen actual evidence of this causing a problem.  In other words, I don't think it is anything to be too concerned about.   

I do think it  is a good idea to use a class object's Dispose or Close method when available.  This gives the object a better chance of being collected in a timely fashion. 

Thanx for bringing up the subject. It is an interesting one.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on June 18, 2013, 02:44:41 PM
Thanx for bringing up the subject. It is an interesting one.
After a good night's sleep and some other research I decided it makes no sense to move perfectly good Excel/Office COM code to the CLR. Also, I ran a test PS->Excel->WB script, closed all objects and the instance of Excel was still in the Task Manager. Modifying the PS code to include the call to the GC and it was not.
Enough of intellectual curiosity. I plan to explore a range of other assemblies and classes but again not directly related to a project at work. Perhaps the Beta forum would be an appropriate place for such posts.

td

Quote from: stanl on June 19, 2013, 08:28:10 AM
Also, I ran a test PS->Excel->WB script, closed all objects and the instance of Excel was still in the Task Manager. Modifying the PS code to include the call to the GC and it was not.

That should never happen.  Did you call the 'Dispose' method on the PowerShell instance?
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on June 19, 2013, 09:05:50 AM
That should never happen.  Did you call the 'Dispose' method on the PowerShell instance?
Of course, the issues is that PS creates a COMObject (for Excel) and calls the Quit method, but the Excel instance is not released. This is not always the case, but it can happen and the test involved some heavy Excel lifting (and was suggested in the PS blog that also suggested calling the GC). Back to my original point: no need to go the extra distance from COM to automate Excel just because the CLR is available.

td

QuoteOf course, the issues is that PS creates a COMObject (for Excel) and calls the Quit method, but the Excel instance is not released. This is not always the case, but it can happen and the test involved some heavy Excel lifting (and was suggested in the PS blog that also suggested calling the GC). Back to my original point: no need to go the extra distance from COM to automate Excel just because the CLR is available.

Yes, the Office classes are simply interop wrappers for office COM objects. That much is well known and obvious.  However, the topic of this thread is garbage collection and it doesn't say much for the quality of the CLR wrappers or the PowerShell implementation, if you have to use garbage collection to release unmanaged resources.   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Not wishing to beat the dead horse I did write "this is not always the case". I tend to work with fairly intensive Excel automation, and my concern was with using the GC in these extreme cases.
I might add that the original sources I encountered on the subject referenced .NET 3.0 and my understanding is that the GC has added intelligence in 3.5/4.5.

td

Quote from: stanl on June 20, 2013, 05:21:21 AM
Not wishing to beat the dead horse I did write "this is not always the case". I tend to work with fairly intensive Excel automation, and my concern was with using the GC in these extreme cases.

If you have the resources of a MSFT, you can do better than "not always."  Particularly given how MSFT markets the benefits of the product.

Quote
I might add that the original sources I encountered on the subject referenced .NET 3.0 and my understanding is that the GC has added intelligence in 3.5/4.5.

Most of the documented GC changes in the latest versions of the FCL and CLR have to do with large object heap fragmentation and adding  concurrent collection to the workstation GC model.  If anything, those kind of changes could increase the likelihood of the out of sequence releases of COM objects and COM server dll unloads that is almost always the cause of hanging  COM client processes. 

There is a certain amount of irony in MSFT claiming dotNet is better than COM because you don't have to worry about the "plumbing." But then they end up using it themselves and forcing the unsuspecting dotNet user to worry about the GC "plumbing."


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Then, with your permission we can close this thread with your original [this is an interesting subject].

td

Well, at least we now will be able to immediately advise users on how to work around hanging COM server processes when using Office dotNet classes, if it should ever come up.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade