Hang on SomeObject.Free. Check if object is already free in FPC? - delphi

if if have an object (in my case TJSONData) and I want to free this object the programm flow sometimes hangs at this position. I already have a construct like the following in my code but it seems to not fit the case some times:
if Assigned(MyRecord.MyJSONData) then
begin
MyRecord.MyJSONData.Free;
end;
I can reproduce this behavior in tests if I try to free an object two times. In my program this should normally not happen but now my real question:
Is there a way to check if the object is already free? Or do I need to use also FreeAndNil();?

The Assigned function checks to see if a reference is not nil. It
returns True if not nil, and False if nil.
Obviously when you free the object and do not set reference to nil it will pass on next Assigned check (reference <> nil) and will be attempted to free again. But the reference (pointer) is already dangling (pointing to freed or worse, changed, memory).
Generally you should set your references to nil or better - use FreeAndNil function. This way each time you will want to access the freed object it will be nil and thats your check.

There was a large thread in Delphi forum (the tread that eventually crushed the forum) about FreeAndNil.
Common point was that for 95% of tasks you should not check if an object is alive, you should know it beforehand and architect the program so that you always know and never need those checks.
Some survived or revived links are at http://www.theregister.co.uk/2012/01/16/verity_stob_sons_of_khan_2011/print.html and at https://forums.embarcadero.com/message.jspa?messageID=413796

Related

Does dart reuse memory for previously used instances?

It is hard to find a good heading for this, but i think my problem comes clear if i post a small code snipped:
SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM
instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM
My question is now, is the used RAM that was allocated at the first construction reused at the second construction? Or is the RAM of the first instance marked as unused for the garbage collector and the second construction is done with a completely new instance with a different portion of RAM?
If the first is true, what with this:
while(true) {
final SomeObject instance = SomeObject(importantParameter);
}
Will then, each time the while is repeated, the RAM be reused?
It's unspecified. The answer is a resounding "maybe".
The language specification never says what happens to unreachable objects, since it's unobservable to the program. (That's what being unreachable means).
In practice, the native Dart implementation uses a generational garbage collector.
The default behavior would be to allocate a new object in "new-space" and overwrite the reference to the previous object. That makes the previous object unreachable (as long as you haven't store other references to it), and it can therefore be garbage collected. If you really go through objects quickly, that will be cheap, since the unreachable object is completely ignored on the next new-space garbage collection.
Allocating a lot of short-lived objects still has an overhead since it causes new-space GC to happen more often, even if the individual objects don't themselves cost anything.
There is also a number of optimization that may change this behavior.
If your object is sufficiently simple and the compiler can see that no reference to it ever escapes, or is used in an identical check, or ... any other number of relevant restrictions, then it might "allocation sink" the object. That means it never actually allocates the object, it just stores the contents somewhere, perhaps even on the stack, and it also inlines the methods so they refer to the data directly instead of going through a this pointer.
In that case, your code may actually reuse the memory of the previous object, because the compiler recognizes that it can.
Do not try to predict whether an optimization like this happens. The requirements can change at any time. Just write code that is correct and not unnecessarily complex, then the compiler will do its best to optimize in all the ways that it can.

How to check if an object is already destroyed or not?

I have created an object
I passed it to somewhere else as parameter. Somewhere else has Free the object which out of my control.
At the end my coding, I try to check if the object is valid then destroy it. The Assigned() method returned true (seems it is because the variable storing the object reference address). However, the referenced object ready destroyed and I got an exception.
My question is, how could I check if an object is already destroyed? What else other than Assigned() can check the object still exists or not?
program Project1;
uses System.SysUtils;
type TObj = class
public
Name: string;
end;
var AnObj, AnObj2 : TObj;
begin
try
try
AnObj := TObj.Create;
AnObj.Name := 'Testing';
AnObj2 := AnObj; // AnObj passed to other procedures as param
FreeAndNil(AnObj2); // somewhere else "Free" the object out of my control
// as a result, AnObj is still assigned but the object is destroyed
finally
if Assigned(AnObj) then // AnObj is assigned, HOW COULD I IMPROVE HERE?
FreeAndNil(AnObj); // Exception: Invalid pointer operation
end;
except
on E:Exception do
writeln(E.Message);
end;
readln;
end.
How to check if an object is already destroyed or not?
Short answer is you can't. There is no mechanism that will allow you to to check validity of object under manual memory management.
If you want to track validity for debugging purposes, you can use custom memory manager (like FastMM in full debug mode) that can track all references and will report when you access dangling pointers.
FreeAndNil in combination with Assigned only works when you have single reference to an object. If you have more it falls apart because FreeAndNil can nil only the reference you called it upon. All other references will become dangling pointers and Assigned cannot detect dangling pointers.
In a nutshell, Assigned works only when reference points to valid object instance or contains nil value. Under manual memory management you have to keep track and make sure that your reference always contains valid value if you need to use Assigned.
Using Assigned when you keep single reference to an object
If you have single reference to object, you can use Assigned for lazy initialization pattern where you will create object instance if it is not already created. But you have to make sure that object reference contains nil reference in the first place.
Object references will be automatically initialized to nil only if they are class fields, object instance fields or global variables.
If you don't plan to reuse that object reference once it is released you can use Free for releasing its memory.
If you have reusable reference, where you want to create and release object instance multiple times, you have to use FreeAndNil, or set reference to nil after you call Free. That is the only way you can ensure Assigned will work after object is released. Again, this Assigned/FreeAndNil pattern only works if you keep one and only one reference to that object.
Using Assigned when you keep multiple references to an object
If possible don't ever keep more than one reference to an object instance. If you have scenario where you really must keep multiple references to an object instance you need to implement some mechanism that will ensure you can notify all references that object is no longer valid.
There are several ways to do so:
Using interfaces - their automatic memory management will prevent dangling pointers
Using TComponent as base class - where you can use its notification system to get notifications when object instance is going to be destroyed
Implement your own notification system to manage all references to an object instance
Note: For 2. and 3. you have to manually nil all references to an object when you get notification it will be destroyed. If you don't do that any reference you don't set to nil, will be invalid, dangling reference any using Assigned upon it will fail to work properly.
If you have situation when you passed object as parameter, and some code beyond your control called Free on that object then you are dealing with ownership transfer. You created the object, but then you transferred ownership (responsibility to release object) to some other code. After that you should not use that object reference again (except in some narrow scenarios, when you know for sure that immediate code after transfer is complete will not trigger object release).
You can use object reference you don't own (after you have transferred ownership) only if there is some notification mechanism (as mentioned earlier) that can notify you when object instance is released.
Also you should never, ever free objects you don't own. In your example, even if you can get notified that object is going to be destroyed all you can do is nil the reference that points to it. You should not attempt to release it.

Should I set object to nill in Swift

I am reading someone's code. He set AVAudioPlayer to nil after user clicking a button to stop the audio from playing. I am wondering should we set object to nil after we don't need it anymore? Or should we set AVAudioPlayer to nil after we are trying to stop playing the audio?
Usually, this is not needed but there are exceptions. When you have a local variable, you almost never need to set it to nil because when it goes out of scope, it will be destroyed anyway.
When you have a variable on instance scope (a property), it's more difficult because you often want to release the memory while the instance is still being used (for example, a property in a controller). In this case, setting to nil is completely correct because you have no other way to remove the object from memory.
The fact that it's a AVAudioPlayer instance shouldn't be relevant although the player usually takes a big chunk of memory so it's good to watch for its instances.
If you have a strong member variable, you may be able to free a significant amount of resources earlier on by deliberately disposing of objects by setting them to nil when no longer required. The benefit will depend on the specific type of object in question.

Why is an object not automatically set to nil when its reference count becomes 0?

In a non ARC Objective C environment, I understand why we have to release an object: to free the memory allocated for it; I understand why we have to set it to nil afterwards (if we are sure nothing else needs the instance / nothing else still has a hold on the object): to avoid dangling pointers.
However my question is, if all objects release their hold on an object, "carInstance" for example, resulting in its reference count going down to 0, why oh why does that Not automatically make it nil?
If reference count is now 0, is the object still usable in any way? Or is this just one of those things we have to do just because that's how not having garbage collection works (can't be, there must be a reason)
The simple answer is that the manual memory management model that was used pre-ARC is lightweight and simple. The behavior you are wishing for is the behavior you get with weak pointers under ARC; and it requires extra work by the OS, to track weak pointers and nil them out when the object is reclaimed. It's doable, clearly, but the cost of implementing it, as well as the computational overhead, wasn't deemed worthwhile until Apple was already rolling out the extra work of implementing ARC.
After an object is deallocated, the dangling pointer is worse than useless: it is downright dangerous. Referencing it while it points to unallocated memory produces an exception; referencing it after it is randomly reassigned to another object or some other memory allocation will typically produce an 'object does not respond to selector' error.

ARC in iOS questions

~ Will ARC always release an object the line after the last strong pointer is removed? Or is it undetermined and at some unspecified point in the future it will be released? Similarly, assuming that you don't change anything with your program, will ARC always be the same each time you run and compile your program?
~ How do you deal with handing an object off to other classes? For example, suppose we are creating a Cake object in a Bakery class. This process would probably take a long time and involve many different methods, so it may be reasonable for us to put the cake in a strong property. Now suppose we want to hand this cake object off to a customer. The customer would also probably want to have a strong pointer to it. Is this ok? Having two classes with strong pointers to the same object? Or should we nil out the Bakery's pointer as soon as we hand off?
Your code should be structured so the answer to this doesn't matter - if you want to use an object, keep a pointer to it, don't rely on ARC side effects to keep it around :) And these side effects might change with different compilers.
Two strong pointers is absolutely fine. ARC will only release the object when both pointers are pointing to something else (or nothing!)
ARC will implement the proper retains and releases at compile time. It will not behave any different than if you put them in there yourself so it will always do the same compilation and to answer your question should always behave the same. But that said it does not mean that your object will always be released immediately after the pointer is removed. Because you never call dealloc directly in any form of objective C you are only telling it that there is no reference count and that it is safe to release. This usually means that it will be released right away though.
If you pass an object from one class to another and the receiving class has a strong property associated with it and the class that passes it off eventually nils its pointer it will still have a reference count of at least 1 and will be fine.
Ok, first this answer might helpt you also a little bit: ARC equivalent of autorelease?
Generally after the last strong variable is nilled, the object is released immediately. If you store it in a property, you can nil the property, assign it to something like __strong Foo *temp = self.bar; before you nil, and return that local __strong variable (although arc normally detects the return, and inferes the __strong byitself).
Some more details on that: Handling Pointer-to-Pointer Ownership Issues in ARC
DeanWombourne's answer is correct; but to add to (1).
In particular, the compiler may significantly re-order statements as a part of optimization. While method calls will always occur in the order written in code (because any method call may have side effects), any atomic expression may be re-ordered by the compiler as long as that re-order doesn't impact behavior. Same thing goes for local variable re-use, etc...
Thus, the ARC compiler will guarantee that a pointer is valid for as long as it is needed, no more. But there is no guarantee when the pointed to object might be released other than that it isn't going to happen beyond the scope of declaration. There is also no guarantee that object A is released before B simply because A is declared and last used before B.
IN other words, as long as you write your code without relying on side effects and race conditions, it should all just work.
Please keep you code proper as it has diffrent behaviour on diffrent complier.

Resources