Designing .NET Framework Class Libraries: Designing for a Managed Memory World (March 16, 2005)
Posted: April 23, 2005
Please note: Portions of this transcript have been edited for clarity
Introduction
frankred [MS] (Moderator):
Hello & welcome to today’s Designing .NET Class Libraries chat on Designing for a Managed Memory World.
Joe Duffy [MS] (Expert):
Welcome to the chat everyone. Thanks for coming along. My name's Joe Duffy, and I'm a Program Manager on the CLR team. I've been doing quite a bit of work lately around finalization & dispose coding patterns, so I'm pretty excited about today's discussion... I have a blog here: https://www.bluebytesoftware.com/blog/ that you might be interested in. Let the grilling begin. :)
frankred [MS] (Moderator):
Now, let’s introduce our knowledgeable experts...
BradA [MS] (Expert):
Welcome to the Chat - I am Brad Abrams a PM on the CLR team and I gave the talk on memory and resource management we are chatting about today.. Oh, and BTW, the Avalon and Indigo CTP *just went live* https://msdn.microsoft.com/en-us/
Start of Chat
frankred [MS] (Moderator):
Q: A lot of people in here for the security chat... can you address that?
A: I'm investigating what happened to the security chat. One moment please...
frankred [MS] (Moderator):
Q: Do you know there the Event Log chat is?
A: I'm investigating this issue as we speak...
BradA [MS] (Expert):
Q: Should the private field 'disposed' be set to true in the if block (a la example in Ch13 of the presentation) or out of the if block (a la section 3.5 of Krzysztof's white paper on GDN)?
A: public class Resource: IDisposable {
private bool disposed = false;
pubic int GetValue () {
if (disposed) throw new ObjectDisposedException();
// do work
}
public void Dispose() {
if (disposed) return;
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
// Dispose dependent objects
disposed = true;
}
// Free unmanaged resources
}
~Resource() {
Dispose(fals
BradA [MS] (Expert):
Q: Should the private field 'disposed' be set to true in the if block (a la example in Ch13 of the presentation) or out of the if block (a la section 3.5 of Krzysztof's white paper on GDN)?
A: Sorry, I should have said more... This is how I would do it... there is no reason to do it outside of the block as that is the finalizer and no one else can reach the object...
Krzysztof Cwalina (Expert):
Q: When I get an image from a stream, I use a static method FromStream. When I get an icon from a stream, I use an instance constructor. Why?
A: Image is an abstract type, so you cannot instantiate it. When you call FromStream it actually creates and returns a subtype of Image. Icon is a concrete type that can be instantiated using a constructor. It could also be instantiated using a FromStream method, but the general preference for API designers is to use constructors, unless a factory method (like FromStream) would be significantly better.
Joe Duffy [MS] (Expert):
Q: If I have a component using (not inheriting from) an object which implements IDisposable, should I also implement IDisposable? I've seen discussion both ways and it wasn't quite clear to me from the presentation.
A: I assume you mean "using" to mean that you have a field containing an IDisposable instance. In this case: Yes, you should. In it, all you need to do is invoke Dispose on the IDisposable component. This way you give users of your class an easy way to control the lifecycle of resources that your class owns. This assumes your resource never lives longer than your component--in this case, it might be a mistake. I.e. somebody might have obtained a reference to your IDisposable resource, stored it away, and you go an dispose of it out from under them. This would be bad. Note that your type doesn't need a finalizer... presumably the IDisposable type you are using has one.
NicholasPaldino_MVP (Expert):
RonO: Basically, if you have a field in your class which is of a type that implements IDisposable, then you should implement IDisposable, and make sure you are forwarding the call when your implementation is called (according to the pattern)
Krzysztof Cwalina (Expert):
Q: what is the difference between managed an unmanaged memory about the performance ?
A: Rico's blog is the best source of information on this topic. See https://blogs.msdn.com/ricom/
BradA [MS] (Expert):
Q: This is too general of a question, I admit, but nevertheless: As far as memory consumption is concerned does it typically pay off more to worry about instantiating too many objects at runtime or having too many classes in an application?
A: You are right, it is a fairly general question... and I would reinforce what rico said last week -- you need to measure... But the way to think about it intuitively is that there is some overhead for both types and instances that is roughly equivalent... the type fixed overhead is higher, but both could be dominated by your variable costs (static and instance fields for example). So what you should really look at is number of allocations... how many types are you loading vs. how many instances created... In my experience the problem is usually too many instances created.
Krzysztof Cwalina (Expert):
Since, lots of people here came for the EventLog chat, I thought I would ask an EventLog question. Have you had a chance to use the managed EventLog APIs? Any feedback on the APIs? I am actually (coincidentally) a Program Manager for the System.Diagnostics namespace (which includes EventLog)
frankred [MS] (Moderator):
Q: Does anyone know what happened to the Event Log Chat for today?
A: Apparently the MSDN Chat room was double-booked. Unfortunately, the only thing we can do at this point in time is reschedule the Event Log chat. :$ Please check https://www.microsoft.com/communities/chats/default.mspx for an updated date + time.
BradA [MS] (Expert):
Q: In building components, should I give any consideration to memory alignment or field ordering?
A: For just a pure managed app (no interop) the CLR will layout your object in the best way it can... do you should not worry about that... we have talked about doing some hot and cold splitting in the future... The best thing you can do is worry about memory locality... doing that poorly causes page faults even in managed code. the principle to understand is that objects that are allocated close in time are allocated close in space... so that can give you locality.
BradA [MS] (Expert):
Q: can i create a class library from visual basic net standard edition ? ( assembly )
A: Yes... you an create a class library from any VS SKU....
Krzysztof Cwalina (Expert):
Q: What is the official preference between interfaces and abstract base classes for redistributable binaries? Also under what circumstances should I seal my classes, for performance only?
A: The general preference is for abstract classes. They allow you to evolve the API after it shipped. Interfaces should be used to simulate multiple inheritance and to create polymorphic hierarchies of value types. I started to post on this topic on my blog : https://blogs.msdn.com/kcwalina/archive/2004/10/24/246947.aspx and recently wrote much more on this and will post in the next couple of weeks.
BradA [MS] (Expert):
Q: I see that the Class Designer for C++ has been dropped from VS 2005. Is it expected that everyone who is building classes for .NET should use C# anyway?
A: Certainly not! We are building the .NET Framework in WinFX in C#, C++ and VB.... In fact I just learned this morning that an important part of Avalon is built in VB... I am not sure why the class desinger was dropped for C++, but send me a mail and I will follow up (brada@microsoft.com)
Krzysztof Cwalina (Expert):
Q: What is the official preference between interfaces and abstract base classes for redistributable binaries? Also under what circumstances should I seal my classes, for performance only?
A: ... as to sealing. The general guidelines say not to seal types but rather try to seal individual (all) methods. Again, I will try to post about this to the blog (now that I know it interests people).
Joe Duffy [MS] (Expert):
Q: When do I need to use Marshal.ReleaseComObject? Is it only when a COM object has been instantiated using Reflection?
A: When doing COM interop thru RuntimeCallableWrappers (RCWs), you should only use ReleaseComObject when you know *for sure* that you're entirely done using the wrapper in an entire appdomain. This ends up as a Release on the refcount. Otherwise, the RCW itself will release once it gets finalized. But keep in mind, we share the refcount across an entire managed appdomain, so you need to release refs with care.
Krzysztof Cwalina (Expert):
Q: EventLog response: Wasn't it just ported from the VB EventLog object?
A: The design vas influenced by the VB APIs, but it's not a direct port.
BradA [MS] (Expert):
Q: Brad: you mentioned something about placing an unmanaged resource (or something that needs cleanup) in a private class instead of making your public API class IDisposable. So, you create the private class using the IDisposable pattern then instead, right?
A: I think that was mainly about making sure the smallest possible class is finalizable... that is where you should use a private class and make sure your larger, feature rich public class is not finalizable. that cuts down on memory usage... Types that are IDisposable likely need to propagate out to client code...
BradA [MS] (Expert):
Q: On System.Windows.Forms, forms inherits from Control wich inherits from System.ComponentModel.Component wich implements IDisposable. Since controls added to the Form via the designer are implemented as fields (of the form), do I have do dispose anything..
A: In just the normal usage of a form, likely you don't... but if you are showing a complex form then want to distory it and return the resources back right then, then yes, you should call Dispose on that...
BradA [MS] (Expert):
Q: How do I catch a doubleclick in my datagrid? :S
A: I am sorry, i am not sure this is the right chat...
BradA [MS] (Expert):
Q: Please help..It just happend..I was in Add /remove programs when my cat went accross the keybord....Anyway...I do not know what got deleted..I do know that a program was removed, Is their someway to find out..I have use the MS DATA BASE an all..no luck
A: Wow -- sorry about that... I am not sure... Did you try https://support.microsoft.com/Default.aspx
Krzysztof Cwalina (Expert):
Q: I've never seen component getting asign to a value not null... what is component used for?
A: The components collections hold all children (compponents) of a form.
BradA [MS] (Expert):
Q: but in the proyect type i don't have that option. only can add class module. I understand that a net library contains many class modules !!!
A: File/New Project/Class Library... does that work for you?
Krzysztof Cwalina (Expert):
Q: The designer only assigns null to it: and nothing else.. private System.ComponentModel.Container components = null;
A: I think if you drop components on the form (like EventLog component for example), the designer will add the component to the collection.
BradA [MS] (Expert):
Q: i have a C# web application and all of the forms inherit a System.Web.UI.Page that ill call "MyPage". My understanding is that i should be able to use Request and Response from this base Page but I am getting an error message, why?
A: I am sorry, I am not sure this is the right chat for you... did you try over on https://asp.net?
BradA [MS] (Expert):
Q: I understand that a net library contains many class modules or i mistaked ?
A: That is right...
BradA [MS] (Expert):
Q: Are there any plans in the works for helping discover which objects should be disposed? Hard as I try, I seem to always miss one or two. :$
A: We have been talking about getting some FxCOp rules to help... they could flag any time an IDisposable object goes out of scope without dispose being called... would that help?
Joe Duffy [MS] (Expert):
Q: Are there any plans in the works for helping discover which objects should be disposed? Hard as I try, I seem to always miss one or two. :$
A: Also, something you might be interested in checking out. The new C++/CLI version does deterministic finalization
Krzysztof Cwalina (Expert):
Q: Krzystof: But nothing gets asign to it... Is it a bug of the Windows Forms designer?
A: I see, this is strange. Maybe it's a bug. Please email me at kcwalina@microsoft.com and I will find people who own this code and find out.
BradA [MS] (Expert):
Q: BradA: FxCop would help
A: Cool -- I will pass on the vote...
Joe Duffy [MS] (Expert):
Q: Are there any plans in the works for helping discover which objects should be disposed? Hard as I try, I seem to always miss one or two. :$
A: Oops. Answer got cut off. The new C++/CLI has "determinstic finalization" which does its best job to auto-Dispose of variables when they go out of scope. This is one of their premium features. Would love any feedback on how this might help C# developers, or other suggested improvements.
BradA [MS] (Expert):
Q: no, seems to me that only the visual studio net edition include that proyect type, not the standard edition. what can i do about that ?
A: Wow -- really... I am not sure about that... You can certainly do that at the commandline... drop me a mail and we can talk about it off line...
BradA [MS] (Expert):
Q: FxCop rules would be a step in the right direction (for me, at least). Unfortunately, running FxCop against our assemblies isn't a requirement here.
A: Maybe baking it in as we are with VS2005 will help...
BradA [MS] (Expert):
Q: BradA: Any news on the book about API Usability you mencioned on the other chat? Can you say any thing about it?
A: It is definitely something we are seriously thinking about... but we don't have anything to announce at this time.... What would you like to see covered in such a book?
BradA [MS] (Expert):
Q: Just out a curiosity how likely is it with something simple like a DataSet to live past Gen0 if I don't call Dispose() on it?
A: Guaranteed. If it implements a finalizer it will live past gen0…
BradA [MS] (Expert):
Q: no, seems to me that only the visual studio net edition include that proyect option, not the visual basic standard edition. what can i do about that ?
A: Hmm.. I guess I have it wrong... I'll look into it more... but you can always do this on the cmdline of course, but that is a little ugly...
Joe Duffy [MS] (Expert):
Q: Joe: I was thinking about deterministic finalization earlier today. I don't need it, I would like to have some indication of when an object is out of scope. I'd like to have some interface with a method that automatically gets called when out of scope.
A: You can use the C# 'using' keyword for this, which I think is what you're after. If you are careful to wrap any use of a disposable object in using(foo){}, dispose is called when you fall out of scope. Note that a few teams have begun to use this construct for other interesting (not just resource cleanup) patterns. For example, System.Transactions in v2.0 uses this to control transactional scope.
BradA [MS] (Expert):
Q: BradA: All that stuff covered in the class going a little deeper. I think designing good APIs will become even more important when designing APIs that will be exposed by WebServices or other channels.
A: Cool - thanks
Krzysztof Cwalina (Expert):
Q: Given the pattern presented on the class, Do I really have to check disposed on every method? Could the compiler or language help me with this?
A: You need to check in every method that wants to use the disposable resource. Compilers currently don't support this directly, but we are aware that managing resources is difficult and we will continue trying to make it simpler.
Krzysztof Cwalina (Expert):
Q: Joe: 'using' is good, but it only works for Dispose. What prompted me to consider this was the BCL blog entry on Tracing. It'd be great to wrap a tracing object and spit out a message. Then spit out a "done" message when out of scope.
A: you can do it:
BradA [MS] (Expert):
Q: BradA: Can you comment on SLAR v2? How were the reviews, etc?
A: That is going very well... we are almost done... we are fixing the last few samples based on review comments (i got a ton) and pouring them in.. we are a few weeks later than I wanted to be... but we are only a week or so from releasing the book to AW for their work... so 3-4 months before it hits the streets....
BradA [MS] (Expert):
Q: what is your email ?
A: me? brada@microsoft.com
frankred [MS] (Moderator):
We're almost out of time, so get your last questions in!
Joe Duffy [MS] (Expert):
Q: Joe: 'using' is good, but it only works for Dispose. What prompted me to consider this was the BCL blog entry on Tracing. It'd be great to wrap a tracing object and spit out a message. Then spit out a "done" message when out of scope.
A: I agree a more general version of this would be great in the future. People have begun to overload Dispose to do this--there's nothing that constrains what you can do inside of it. But true, putting Dispose there red flags your type and people will think it manages resources, so it's a little weird... for example using (TransactionScope t = new TransactionScope()) { /*...*/ t.Commit(); } is strange since TxScope doesn't manage resources. There might be room for AspectOrientedProgramming-ish (AOP) things in the future. There are a few open projects out there already to enable such things on the .NET Framework. I'd suggest Googling or looking on MSN Search for more info.
Krzysztof Cwalina (Expert):
Q: (cont) I guess I could implement IDisposable on that wrapper, but then I have to use 'using' in every place I was tracing.
A: Oh, so now you are asking about aspect oriented programming in .NET :-)
BradA [MS] (Expert):
Q: It would be great to see other books following the style of SLAR's commented annotations... for all the other namespaces
A: that is actually the vision I had at the very start.. we will have to see if there is the demand to warrent such a thing...
Joe Duffy [MS] (Expert):
Q: Is there going to be a better model in VS2005 for dispose. Two different methods one in Component and one from IDisposable one that takes a boolean all that is confusing.
A: We recently did a lot of work to make it clearer. For people using Disposable types, you need to know one thing: just call Dispose (and in most cases, through C#'s 'using' statement). For implementors, the world is a little more complicated. One major decision point... Are you inheriting from a Disposable type? If so, just override protected virtual void Dispose(bool), put your new logic in there, and just make sure to call base.Dispose(bool) at the end. Otherwise, you need to set up your type. This consists of implementing IDisposable with Dispose() calling Dispose(true), and a new protected virtual void Dispose(bool) that does your cleanup logic. As with anything that relies on convention, it's tough to get right 100% of the time. Watch my blog https://bluebytesoftware.com/blog/ for a post on this pattern in the next couple weeks. Also, in VS2k5, we'll have new FxCop rules to help you do this right.
BradA [MS] (Expert):
Q: Why was SLAR, the C# one and the CLI one released through AW instead of MS Press?
A: I love MS-Press, I think they do very good work... but with these standards related books we wanted to reach out to an audience that may not be in the MS camp today... we want to get academic folks, Linux folks, etc... a "neural" press with a very good reputation seemed like the best call...
frankred [MS] (Moderator):
Alright. We’re out of time. I hope everyone had a good time and got answers to all of their questions. If you have more questions please visit the CLR team blogs https://msdn2.microsoft.com/netframework/aa569259.aspx section on the .NET Framework developer center. Please join us again next Wednesday for the next chat in the Designing .NET Class Libraries https://msdn2.microsoft.com/netframework/aa497250.aspx series.
BradA [MS] (Expert):
Q: When is .NET FW 2.0 Beta 2 expected?
A: Give us a couple of more months... we are in the end game, but we want to get it really solid...
Joe Duffy [MS] (Expert):
Q: Great chat!
A: Thanks for coming along everyone! Stay tuned next week... where we delve into the dark world of unmanaged interop... :)
BradA [MS] (Expert):
Well, thanks for comming, join us next week for interop! --brad
Krzysztof Cwalina (Expert):
Thanks for all who chatted with us.
Top of page