Regarding Delphi memory management, what are your design strategies ?
What are the use cases where you prefer to create and release Objects manually ?
What are the uses cases where Interfaces, InterfacedObjects, and their reference counting mechanism will be preferred ?
Do you have identified some traps or difficulties with reference counted objects ?
Thanks for sharing your experience here.
Whenever you share objects between threads it is better to use interfaces. A shared object doesn't necessarily have one identifiable owner, so letting the thread that gives up the last reference to the interface free the implementing object is a natural fit. See the OmniThreadLibrary for a good example of how to make use of interfaces both for design and for overcoming some of the complicated ownership issues in multi-threaded code.
You should always prefer interfaces unless it's not possible due to VCL restrictions. I suspect that, had interfaces been available in Delphi 1.0, the VCL would have turned out very differently.
One minor consideration is to watch out for reference cycles. If A holds an interface to B and B holds an interface to A, they will both live forever.
Related
Retain counts are the way in which memory is managed in Objective-C. When you create an object, it has a retain count of 1. When you send an object a retain message, its retain count is incremented by 1, which we know that ARC does it automatically but how it does what is the technique it use??
And I still wonder if memory management is done automatically then why sometimes we get bad access error for objects allocations or retrieval.
I have already gone through this link:- https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
I think ARC (done by the compiler at compilation time, by inserting retain/release command where 'necessary') relies on the scope of variable, the block of code where they are defined (i.e. initialized) and if its value is stored in another variable whose scope is broader than the initial variable's scope.
That's why you have to declare more precisely the type of variable access and storage: to inform the compiler your intentions with a variable.
But I think too that ARC can't see further than the current file. ARC is more tricky with global variables and inter-files dependencies.
So, Apple a more complex variable's declaration grammar to replace a very simple (IMO) retain/release pattern. So developers don't have to worry about memory management.
That enable Apple ecosystem to be accessible to a lot more developers used to managed languages (like web developers) to develop for iOS.
I think it is a mistake to make developers believe you can develop efficiently without having to understand such a fundamental concept in IT as memory management.
But more developers for iOS means more programs developed and a more stable ecosystem in term of activity, so more revenues for Apple :-)
You would be better off reading the ARC docs: https://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
ARC will manage the memory for you, but it cannot stop you from writing programming errors such as only holding weak references to an object.
In what circumstances should I be using this feature?
How exactly mature is it?
What are the pros and cons?
What problem does it solve?
Is it specific to MonoTouch, Mono GC, or reference counting in ObjC?
Here are some quick, high-level (and out or order) answers to your questions...
Is it specific to MonoTouch, Mono GC, or reference counting in ObjC?
It allows sgen, the mono garbage collector, to work more closely with Objective-C reference counting. That awareness is not needed for Mono (or Mono for Android) so it's specific to MonoTouch.
How exactly mature is it?
As the UI says: Experimental preview. So while we know it works it has not yet seen a wide usage inside applications (compared to the default GC). It's more a direction than a destination (i.e. it will likely evolve).
You're more than welcome to test it, use it (if it proves useful in your situation) and report your findings/experiences with it. However it's not fully supported, e.g. you might hit a bug that we can't immediately fix or workaround (beside asking you to go back to the default settings).
What problem does it solve?
The coexistence of a garbage collector and the reference counting of Objective-C is very complex subject. MonoTouch tries it best to hide (most of) complexity of this to the developers.
Most of this is done inside the runtime (e.g. by using the backing fields). This extension to sgen is meant to have the GC itself (not only the runtime) aware of the needs for reference counting.
What are the pros and cons?
PRO: It saves memory as the linker can remove many of the backing fields that would be otherwise required to ensure we keep a reference to the managed objects. Without those (references to) backing fields the GC would normally collect the instances (while they are still needed by unmanaged code).
CON: We need more feedback, more comparison data (e.g. performance).
I'm trying to design an application that can identify COM objects and their properties on any different application. This is my first time attempting to do so, and I'm not sure where to start even. Ideally, it would be made using Delphi XE2, but I'm open to suggestions.
If I have the CLSID, is there any way to "scan" a running application for what objects were based on it? Or, going another way, is there a better way to list/find active objects in any running application?
Any help is deeply appreciated, as well as any directions towards good documentation on the subject.
Edit: The issue is actually finding out the COM objects in any other application, listing properties and whatever else I need has already been answered in other questions.
There is no way to scan for running COM objects. As soon as they are instantiated - they are just pieces of memory referenced by something else (member interface pointer variables etc).
Sometimes objects are put on Running Objects Table (ROT) and you can retrieve them from there, as already suggested in comments. This attributes for, let's say, <1% of COM object instances, but maybe you are lucky enough to chase for exactly those.
The only way I can think of is hook COM object instantiation in so that you intercept creation and then be able to track your own list of existing instances. This is not an easy way though too (and also it is most likely to be unsafe).
To achieve this you need to either register your class object in the context of running process for the CLSID of your interest and have your class factory receive the instantiation calls. Or, hook CoCreateInstance API, such as with Detours.
Once you are hooking instantiation you have pointers at the moment of object creation and you again need to do something with them. You would want to forward those instantiation calls to the original API, then to track life time of the instances - if you put an extra reference to the object you are likely to alter the original behavior of the application. Otherwise, you have no control to intercept COM object release. Sometimes the COM classes can be created aggregated and you can more or less cleanly embed the original instance in your COM object.
All in all, in general the task does not seem feasible to implement. Having specific CLSID of interest, with a certain luck and quite some effort you might be successful in doing this though.
Dependency Injection is certainly one of the most important concepts when trying to write testable code. But while Java and C# have garbage collection, Delphi has not and normally, object disposal is managed using the ownership-principle (the one who creates the object destroys it). This is nicely supported by the try..finally construct
Obj := TObject.Create;
try
...
finally
Obj.Free;
end;
Now what if one uses dependency injection:
constructor TFileLister.Create(FileSystem: TFileSystem);
Who should now be responsible for destroying the FileSystem object? Does the ownership-principle still work here?
I know that interfaces are a solution to this problem (thanks to the fact that they are reference-counted). But what if there are no interfaces (say in some legacy code)? What other approaches or best practices are there to handle memory management when using dependency injection?
You have to come up with an owner for the FileSystem object. This can be either the entity that creates the TFileLister instances, or you could pass ownership to the file lister, documenting that it will free the file system that was passed to the constructor.
The right approach depends on course on your particular application. For example, if other objects would also use the same file system object, it shouldn't be owned by one of these such as the file lister, but by the object that ties it all together. You could even make the file system object global if it only makes sense to have one of it.
In short, you'll have to do a little more thinking than in Java but that's not necessarily a bad thing.
It's almost always preferable to regard the entity that create an object also to be its owner (i.e. responsible for destroying it).
To understand why I say this, consider the alternative. Suppose that object A creates object B. At some point later it passes B to object C which becomes the owner.
In the period between creating B and handing it over to C, A is responsible for destruction in case of exceptions, or perhaps the selection of a branch that bypasses C. On the other hand, once it has handed off B, A must not attempt to destroy C.
All this can be handled with sufficient care. One approach is that taken by the VCL with TComponent.Owner.
However, if you can find a way to stick to the two standard patterns of ownership then do so.
What are the two standard patterns?
Create in a constructor and assign to a field; destroy in the matching destructor.
Create and destroy inside a single method, with protection provided by try / finally.
I would strongly recommend that you try to shape your code so that all resource acquisition uses one of these two options.
How can you do so in your example? The option that leaps out at me is to use a factory to create your FileSystem object. This allows TFileLister to manage the lifetime of the FileSystem object, but gives you the flexibility of injecting different behaviour into TFileLister.
I disagree with the notion that an object must be destroyed by the one that created it. Many times this is the natural choice but its certainly not the only way of managing memory. A better way to look at it is that an object's lifetime should end when it is no longer needed.
So what options do you have?
Use Interface reference counting
In many cases it is trivial to extract an interface from an existing class so don't shelve this idea just because your working with legacy code.
Use an IoC container that supports lifetime management.
There are a number of IoC containers for Delphi and more are popping up all the time. Spring for Delphi is one that I know of that supports lifetime management. Note: most of these containers target Delphi 2010 or newer so it may be difficult to find one for legacy code.
Use a garbage collector.
The Boehm GC memory manager is the only one I'm aware.
All three of these can be combined with poor man's dependency injection to get the testing benefits while making minimal changes to your legacy code. For those unfamiliar with the term you use constructor chaining to instantiate a default dependency.
constructor TMyClass.Create;
begin
Create(TMyDependency.Create);
//Create(IoCContaineror.Resolve(TMyDependency));
end;
constructor TMyClass.Create(AMyDependency: TMyDependency)
begin
FMyDependency := AMyDependency;
end;
Your production code continues to use the default constructor with the real object while your tests can inject a fake/mock/stub to sense what the class being exercised is playing nicely. Once your test coverage is high enough you can remove the default constructor.
Hi are there any nice videos or other resources on how to use Interfaces in delphi?
I am after the basics and more advanced stuff.
Once you have read stuff on the web you should probably look into code by other programmers to see how (and why) they used interfaces in real code.
For example in the Subversion repository of the dUnit SourceForge site you will find the XPObserver.pas file, which implements the Observer pattern for Delphi, using interfaces. This code is very interesting, as usually in this pattern the observed objects each keep a list of observers, and the observers each keep a reference to the object(s) they observe. A naive implementation using interfaces would create circular references, the interfaces would keep their reference counts from reaching 0, and this would result in memory leaks. The code in XPObserver.pas shows how you can use typecasting to solve this problem.
IMO the most of XP*.pas files are worth a closer look. For example XPInterfacedObject.pas contains an explanation why aggregated interfaces must all use a common reference counter, and presents an alternative solution to TAggregatedObject and TContainedObject as implemented in the VCL.
Not a video, but this explains the basics.
Since COM uses interfaces this online course is also an introduction to interfaces.