When to release IBOutlet? - release

I used Interface Builder to connect GUI elements to IBOutlet in view controller, but not sure when do I need to release them, in viewDidUnload or dealloc? Or both?
Thanks!

Assuming they're properties, you should set them to nil in both viewDidUnload and dealloc, making sure to use the setter. So e.g.
self.imageView = nil;
self.segmentControl = nil;
/* etc */
Setting a retain property to nil has the effect of releasing the object and setting the instance variable to nil (so it's safe to do the same thing again even without gaining a new object in between).
viewDidUnload is called when your view controller's view has been ejected from memory, which can happen when a memory warning occurs and your view controller isn't currently using its view. If you've retained some subviews for yourself (implicitly, via a 'retain' setter or deliberately) and don't release them, they'll stay in memory. You don't want them to do that because you're required to free as much memory as possible upon receipt of a memory warning and you or other processes could be terminated if not enough memory is freed system wide. So it's both to be kind to your user and to be a good citizen.
The same advice applies whether you've got retain or assign properties; if they're retained then setting the property to nil will release, if they're just assigned then setting the property to nil will prevent you from keeping a dangling pointer.

You should release IBOutlets in dealloc.
In viewDidUnload you should release anything you created or retained in viewDidLoad.

Related

Confused about safe publishing and visibility in Java, especially with Immutable Objects

When I read the Java Concurrency in Practice by Brian Goetz, I recall him saying "Immutable objects, on the other hand, can be safely accessed even when synchronization is not used to publish the object reference" in the chapter about visibility.
I thought that this implies that if you publish an immutable object, all fields(mutable final references included) are visible to other threads that might make use of them and at least up to date to when that object finished construction.
Now, I read in https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html that
"Now, having said all of this, if, after a thread constructs an immutable object (that is, an object that only contains final fields), you want to ensure that it is seen correctly by all of the other thread, you still typically need to use synchronization. There is no other way to ensure, for example, that the reference to the immutable object will be seen by the second thread. The guarantees the program gets from final fields should be carefully tempered with a deep and careful understanding of how concurrency is managed in your code."
They seem to contradict each other and I am not sure which to believe.
I have also read that if all fields are final then we can ensure safe publication even if the object is not per say immutable.
For example, I always thought that this code in Brian Goetz's concurrency in practice was fine when publishing an object of this class due to this guarantee.
#ThreadSafe
public class MonitorVehicleTracker {
#GuardedBy("this")
private final Map<String, MutablePoint> locations;
public MonitorVehicleTracker(
Map<String, MutablePoint> locations) {
this.locations = deepCopy(locations);
}
public synchronized Map<String, MutablePoint> getLocations() {
return deepCopy(locations);
}
public synchronized MutablePoint getLocation(String id) {
MutablePoint loc = locations.get(id);
return loc == null ? null : new MutablePoint(loc);
}
public synchronized void setLocation(String id, int x, int y) {
MutablePoint loc = locations.get(id);
if (loc == null)
throw new IllegalArgumentException("No such ID: " + id);
loc.x = x;
loc.y = y;
}
private static Map<String, MutablePoint> deepCopy(
Map<String, MutablePoint> m) {
Map<String, MutablePoint> result =
new HashMap<String, MutablePoint>();
for (String id : m.keySet())
result.put(id, new MutablePoint(m.get(id)));
return Collections.unmodifiableMap(result);
}
}
public class MutablePoint { /* Listing 4.5 */ }
For example, in this code example, what if that final guarantee is false and a thread made an instance of this class and then the reference to that object is not null, but the field locations is null at the time another thread uses that class?
Once again, I don't know which is correct or if I happened to misinterpret both the article or Goetz
This question has been answered a few times before but I feel that many of those answers are inadequate. See:
https://stackoverflow.com/a/14617582
https://stackoverflow.com/a/35169705
https://stackoverflow.com/a/7887675
Effectively Immutable Object
etc...
In short, Goetz's statement in the linked JSR 133 FAQ page is more "correct", although not in the way that you are thinking.
When Goetz says that immutable objects are safe to use even when published without synchronization, he means to say that immutable objects that are visible to different threads are guaranteed to retain their original state/invariants, all else remaining the same. In other words, properly synchronized publication is not necessary to maintain state consistency.
In the JSR-133 FAQ, when he says that:
you want to ensure that it is seen correctly by all of the other thread (sic)
He is not referring to the state of the immutable object. He means that you must synchronize publication in order for another thread to see the reference to the immutable object. There's a subtle difference to what the two statements are talking about: while JCIP is referring to state consistency, the FAQ page is referring to access to a reference of an immutable object.
The code sample you provided has nothing, really, to do with anything that Goetz says here, but to answer your question, a correctly initializedfinal field will hold its expected value if the object is properly initialized (beware the difference between initialization and publication). The code sample also synchronizes access to the locations field so as to ensure updates to the final field are thread-safe.
In fact, to elaborate further, I suggest that you look at JCIP listing 3.13 (VolatileCachedFactorizer). Notice that even though OneValueCache is immutable, that it is stored in a volatile field. To illustrate the FAQ statement, VolatileCachedFactorizer will not work correctly without volatile. "Synchronization" is referring to using a volatile field in order to ensure that updates made to it are visible to other threads.
A good way to illustrate the first JCIP statement is to remove volatile. In this case, the CachedFactorizer won't work. Consider this: what if one thread set a new cache value, but another thread tried to read the value and the field was not volatile? The reader might not see the updated OneValueCache. BUT, recalling that Goetz refers to the state of the immutable object, IF the reader thread happened to see an up-to-date instance of OneValueCache stored at cache, then the state of that instance would be visible and correctly constructed.
So although it is possible to lose updates to cache, it is impossible to lose the state of the OneValueCache if it is read, because it is immutable. I suggest reading the accompanying text stating that "volatile reference used to ensure timely visibility."
As a final example, consider a singleton that uses FinalWrapper for thread safety. Note that FinalWrapper is effectively immutable (depending on whether the singleton is mutable), and that the helperWrapper field is in fact non-volatile. Recalling the second FAQ statement, that synchronization is required for access the reference, how can this "correct" implementation possibly be correct!?
In fact, it is possible to do this here because it is not necessary for threads to immediately see the up-to-date value for helperWrapper. If the value that is held by helperWrapper is non-null, then great! Our first JCIP statement guarantees that the state of FinalWrapper is consistent, and that we have a fully initialized Foo singleton that can be readily returned. If the value is actually null, there are 2 possibilities: firstly, it is possible that it is the first call and it has not been initialized; secondly, it could just be a stale value.
In the case that it is the first call, the field itself is checked again in a synchronized context, as suggested by the second FAQ statement. It will find that this value is still null, and will initialize a new FinalWrapper and publish with synchronization.
In the case that it is just a stale value, by entering the synchronized block, the thread can setup a happens-before order with a preceding write to the field. By definition, if a value is stale, then some writer has already written to the helperWrapper field, and that the current thread just has not seen it yet. By entering into the synchronized block, a happens-before relationship is established with that previous write, since according to our first scenario, a truly uninitialized helperWrapper will be initialized by the same lock. Therefore, it can recover by rereading once the method has entered a synchronized context and obtain the most up-to-date, non-null value.
I hope that my explanations and the accompanying examples that I have given will clear things up for you.

Is it safe to call Dispose on an instance from event handler?

public class MyTask : IDisposable { ... }
MyTask task = new MyTask(() => SomeTask);
task.Completed += (s, e) =>
{
// do something with result
...
// dispose of this instance
((MyTask)s).Dispose();
};
// execute the task
task.Execute();
Clearly I cannot tell when the task will be completed, so the only actual place, as I see it, that i can dispose of this instance is in Completed event.
Is this safe to do?
There is, alas, no general rule as to when it is safe to call Dispose. If Microsoft had specified that Dispose must be safe to call at any time when an object isn't in use, complying with such a rule would seldom have been difficult; in cases where a class might not always be able to perform all necessary cleanup immediately(*), it would generally be possible for it to set a flag and/or otherwise arrange to have necessary cleanup performed at the next opportunity. Unfortunately, Microsoft does not specify that Dispose implementations have to handle asynchronous Dispose requests, nor is there any general way for an object which holds the last useful reference to an IDisposable instance to ask for notification when it would be safe to dispose.
Despite the general lack of assurance as to when it is safe to call Dispose, many particular classes which implement Dispose do offer guarantees as to when it may safely be called. If one knows that a particular object is of a type which can be safely disposed in a particular context, one may dispose it then. Especially in cases where an event from an object may be the only opportunity to Dispose it in a threading context it could know about, and where disposing an object within an event handler would make sense, it should be safe to dispose of the object. Any properly-written event handlers should be prepared for the possibility that the object sending the event may be disposed between the time the system decides that they should run, and the time it actually runs them.
(*) The essential purpose of IDisposable is to allow an object to notify entities which are outside it but are acting on its behalf to the detriment of other entities, that they should no longer do so [e.g. to tell a file system that it should no longer grant an object exclusive access to a file]. Such action is referred to as "releasing resources". The fact that someone holds the last surviving reference to an object may imply that no other thread can be using that object, but does not imply that no other thread is using any non-thread-safe entities whose resources need to be released.

VB6 Memory Leaks Without GDI Leaks

All the advice I've found on debugging memory leaks in VB6 code has focused on GDI leaks. In my situation, however, evidence suggests that I don't have a GDI leak but probably do have a memory leak. What might be some likely candidates for the cause of such a leak, and/or good tools to help me determine the portion of my program which is causing this?
Unfortunately VB6 does not have enough debugging instrumentation to detect object leaks. I'm usually implementing instance book-keeping on my own in every class, form or user control with a couple of helper functions. The basic pattern is like this
Private Const MODULE_NAME As String = "<<class_name_here>>"
#If DebugMode Then
Private m_sDebugID As String
#End If
#If DebugMode Then
Private Sub Class_Initialize()
DebugInstanceInit MODULE_NAME, m_sDebugID, Me
End Sub
#End If
#If DebugMode Then
Private Sub Class_Terminate()
DebugInstanceTerm MODULE_NAME, m_sDebugID
End Sub
#End If
Helper function DebugInstanceInit generates next sequential id and assigns it to m_sDebugID, then stores module name and ObjPtr(Me) in a collection, keyed on the id.
Helper function DebugInstanceTerm removes entry from the collection using m_sDebugID as a key.
This way in every moment of application execution you can dump this instance collection and identify count and type of objects that are allocated but still not terminated. If continuous opening and closing of forms increments object count you are leaking objects probably due to circular references (e.g. collection->entries and entry->collection).
Most frameworks and other languages have this kind of book-keeping built-in (at least in debug builds) but unfortunately VB6 has poor support for source code metadata (MODULE_NAME, FUNC_NAME, LINE_NUMBER) and object lifetime management. Lack of implementation inheritance hurts here too.
Generically, you have to watch for circular references. In VB6, an object will remain in memory as long as it is referenced somewhere. So if you have an object-type variable as a member of a form (for example) then it will be in memory until that form is Terminated (unless you explicilty set it to nother early of course). And that reference chain can be very deep:
Here, FormA is keeping ObjectB and ObjectC in memory:
FormA -> ObjectB -> ObjectC
What you need to watch for is something like this:
FormA -> ObjectB <-> ObjectC
ObjectB has a reference to ObjectC and ObjectC has a back or parent reference to ObjectB. Even if FormA is Terminated or otherwise clears it reference to ObjectB, ObjectB and ObjectC will live forever and represent a memory leak.
good tool for finding memory leaks is deleaker. you can try it. And check yet one thing - are there still GDI leak or not. You must be sure!

Is there a way to detect if an object is locked?

Is there any way to determine if an object is locked in C#? I have the unenviable position, through design where I'm reading from a queue inside a class, and I need to dump the contents into a collection in the class. But that collection is also read/write from an interface outside the class. So obviously there may be a case when the collection is being written to, as the same time I want to write to it.
I could program round it, say using delegate but it would be ugly.
You can always call the static TryEnter method on the Monitor class using a value of 0 for the value to wait. If it is locked, then the call will return false.
However, the problem here is that you need to make sure that the list that you are trying to synchronize access to is being locked on itself in order to synchronize access.
It's generally bad practice to use the object that access is being synchronized as the object to lock on (exposing too much of the internal details of an object).
Remember, the lock could be on anything else, so just calling this on that list is pointless unless you are sure that list is what is being locked on.
Monitor.TryEnter will succeed if the object isn't locked, and will return false if at this very moment, the object is locked. However, note that there's an implicit race here: the instance this method returns, the object may not be locked any more.
I'm not sure if a static call to TryEnter with a time of 0 will guarantee that the lock will not be acquired if it is available. The solution I did to test in debug mode that the sync variable was locked was using the following:
#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place. Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
if (acquired)
{
Monitor.Exit(SyncRoot);
}
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif
Monitor.IsEntered
Determines whether the current thread holds the lock on the specified object.
Available since 4.5
Currently you may call Monitor.TryEnter to inspect whether object is locked or not.
In .NET 4.0 CLR team is going to add "Lock inspection API"
Here is a quotation from Rick Byers article:
lock inspection
We're adding some simple APIs to ICorDebug which allow you to explore managed locks (Monitors). For example, if a thread is blocked waiting for a lock, you can find what other thread is currently holding the lock (and if there is a time-out).
So, with this API you will be able to check:
1) What object is holding a lock?
2) Who’s waiting for it?
Hope this helps.

Is this a safe version of double-checked locking?

Slightly modified version of canonical broken double-checked locking from Wikipedia:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper();
// Atomically publish this instance.
atomicSet(helper, myHelper);
}
}
}
return helper;
}
}
Does simply making the publishing of the newly created Helper instance atomic make this double checked locking idiom safe, assuming that the underlying atomic ops library works properly? I realize that in Java, one could just use volatile, but even though the example is in pseudo-Java, this is supposed to be a language-agnostic question.
See also:
Double checked locking Article
It entirely depends on the exact memory model of your platform/language.
My rule of thumb: just don't do it. Lock-free (or reduced lock, in this case) programming is hard and shouldn't be attempted unless you're a threading ninja. You should only even contemplate it when you've got profiling proof that you really need it, and in that case you get the absolute best and most recent book on threading for that particular platform and see if it can help you.
I don't think you can answer the question in a language-agnostic fashion without getting away from code completely. It all depends on how synchronized and atomicSet work in your pseudocode.
The answer is language dependent - it comes down to the guarantees provided by atomicSet().
If the construction of myHelper can be spread out after the atomicSet() then it doesn't matter how the variable is assigned to the shared state.
i.e.
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper(); // ALLOCATE MEMORY HERE BUT DON'T INITIALISE
// Atomically publish this instance.
atomicSet(helper, myHelper); // ATOMICALLY POINT UNINITIALISED MEMORY from helper
// other thread gets run at this time and tries to use helper object
// AT THE PROGRAMS LEISURE INITIALISE Helper object.
If this is allowed by the language then the double checking will not work.
Using volatile would not prevent a multiple instantiations - however using the synchronize will prevent multiple instances being created. However with your code it is possible that helper is returned before it has been setup (thread 'A' instantiates it, but before it is setup thread 'B' comes along, helper is non-null and so returns it straight away. To fix that problem, remove the first if (helper == null).
Most likely it is broken, because the problem of a partially constructed object is not addressed.
To all the people worried about a partially constructed object:
As far as I understand, the problem of partially constructed objects is only a problem within constructors. In other words, within a constructor, if an object references itself (including it's subclass) or it's members, then there are possible issues with partial construction. Otherwise, when a constructor returns, the class is fully constructed.
I think you are confusing partial construction with the different problem of how the compiler optimizes the writes. The compiler can choose to A) allocate the memory for the new Helper object, B) write the address to myHelper (the local stack variable), and then C) invoke any constructor initialization. Anytime after point B and before point C, accessing myHelper would be a problem.
It is this compiler optimization of the writes, not partial construction that the cited papers are concerned with. In the original single-check lock solution, optimized writes can allow multiple threads to see the member variable between points B and C. This implementation avoids the write optimization issue by using a local stack variable.
The main scope of the cited papers is to describe the various problems with the double-check lock solution. However, unless the atomicSet method is also synchronizing against the Foo class, this solution is not a double-check lock solution. It is using multiple locks.
I would say this all comes down to the implementation of the atomic assignment function. The function needs to be truly atomic, it needs to guarantee that processor local memory caches are synchronized, and it needs to do all this at a lower cost than simply always synchronizing the getHelper method.
Based on the cited paper, in Java, it is unlikely to meet all these requirements. Also, something that should be very clear from the paper is that Java's memory model changes frequently. It adapts as better understanding of caching, garbage collection, etc. evolve, as well as adapting to changes in the underlying real processor architecture that the VM runs on.
As a rule of thumb, if you optimize your Java code in a way that depends on the underlying implementation, as opposed to the API, you run the risk of having broken code in the next release of the JVM. (Although, sometimes you will have no choice.)
dsimcha:
If your atomicSet method is real, then I would try sending your question to Doug Lea (along with your atomicSet implementation). I have a feeling he's the kind of guy that would answer. I'm guessing that for Java he will tell you that it's cheaper to always synchronize and to look to optimize somewhere else.

Resources