// sub// where the named method interacts with the UI// "Workflow" is used as the subscription name within the queue Burrow.Queue.Workflow.OrderMessagevar subscriptionOrder = tunnel.SubscribeAsync<OrderMessage>("Workflow", (message, args) => Dispatcher.BeginInvoke(new Action(() => OnOrderReceived(message, args))));

Wednesday, 25 April 2012

Here is the bad news, you can’t but here’s the good news, using a bit of jiggery pokery you can easily work around it!

Scenario

I had a view containing three ellipses that I wanted to colour based on a property for their data context. The expected result was blue if the value was zero, red if the value was greater than zero and yellow if something went wrong.

The Obvious Approach Doesn’t Work

I had my colours set in my UserControl.Resources so I would like to have used the following code:

public static byte[] Protect(byte[] data) { // Encrypt the data using DataProtectionScope.CurrentUser. // The result can be decrypted only by the same current user. return ProtectedData.Protect(data, _additionalEntropy, DataProtectionScope.CurrentUser); }

Friday, 20 April 2012

The Basics

The garbage collector is an automatic memory manager. It provides the following benefits:

Enables us to develop the application without having to free memory.

Allocates objects efficiently on the managed heap.

Reclaims no longer used objects, clears their memory, and keeps the memory for future allocations.

Provides memory safety by making sure that an object cannot use the content of another object.

Garbage collection is non deterministic and occurs based on following condition:

When system has low physical memory.

The threshold of acceptable memory usage of allocated object has been exceeded on the managed heap. This threshold is continuously adjusted as the process runs.

The GC.Collect method is called.

The Heap

Simplified model of the managed heap

The rules for this simplified model are as follows:

All garbage-collectable objects are allocated from one contiguous range of address space.

The heap is divided into generations so that it is possible to eliminate most of the garbage by looking at only a small fraction of the heap.

Objects within a generation are all roughly the same age.

Higher-numbered generations indicate areas of the heap with older objects—those objects are much more likely to be stable.

The oldest objects are at the lowest addresses, while new objects are created at increasing addresses.

The allocation pointer for new objects marks the boundary between the used (allocated) and unused (free) areas of memory.

Periodically the heap is compacted by removing dead objects and sliding the live objects up toward the low-address end of the heap. This expands the unused area at the bottom of the diagram in which new objects are created.

The order of objects in memory remains the order in which they were created, for good locality.

There are never any gaps between objects in the heap.

Only some of the free space is committed. When necessary,more memory is acquired from the operating system in the reserved address range.

Generations

Garbage collection organizes the managed heap into three generations to handle long live and short live objects:

Generation 0. This is the youngest generation and contains short-lived objects. For example temporary variable. Garbage collection occurs most frequently in this generation.

Newly allocated objects are implicitly generation 0 collections, unless they are large objects (85000 bytes and larger), in which case they go on the large object heap in a generation 2 collection.

Most objects are reclaimed for garbage collection in generation 0 and do not survive to the next generation.

Generation 1. This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects.

Generation 2. This generation contains long-lived objects. An example of a long-lived object is an object in a server application that contains static data that is live for the duration of the process.

Objects that are not reclaimed in a garbage collection are promoted to the next generation. Objects that are not reclaimed in generation 0 garbage collection are promoted to generation 1; objects that are not reclaimed in a generation 1 garbage collection are promoted to generation 2; and objects that survive a generation 2 garbage collection remain in generation 2.

Finalization Queue and Thread

When the GC encounters object with Finalizers that are otherwise “dead” instead of reclaiming the space the objects are added to the Finalization Queue (it’s generation number remains the same). An aptly named Finalization Thread then works through this queue running the finalizers and marking the objects as dead, ready for the next GC.

GC modes

Workstation vs Server

Workstation GC: The default GC mode and on a single-proc machine it’s the only option. A single heap collected at normal priority.

Server GC: Only available on multi-proc machines it creates one GC heap (and thread) per processor, which are collected in parallel at highest priority.

Before .NET 4: Concurrent (Workstation only)

A basic (non concurrent) GC uses a "stop-the-world" strategy. When the GC must run, all applicative (managed) threads stop. The last stopping thread runs the GC, and unblocks all the other threads when it has finished.

Concurrent GC is used on a multi-proc machine to perform full collections (generation 2) concurrently with the running program, therefore minimizing the pause time. This mode is particularly useful for applications with graphical user interfaces or applications where responsiveness is essential.

Remember, Concurrent GC is only used with generation 2; generations 0 and 1 are always non-concurrent because they finish very fast.

Introduced in .NET 4: Background [and Foreground] (Workstation only)

In background garbage collection, ephemeral generations (0 and 1) are collected as needed while the collection of generation 2 is in progress. There is no setting for background garbage collection; it is automatically enabled with concurrent garbage collection. As with concurrent garbage collection, background garbage collection is performed on a dedicated thread and is applicable only to generation 2 collections.

So as to allow the background and foreground threads to play nicely with each other, a staging area is found as the alive (blue) objects move from up the generations.

// Variable for suspending work (such servicing allocated server requests) // after a notification is received and then // resuming allocation after inducing a garbage collection. static bool bAllocate = false;

// This is a good time to induce a GC collection // because the runtime will induce a full GC soon. // To be very careful, you can check precede with a // check of the GC.GCCollectionCount to make sure // a full GC did not already occur since last notified. GC.Collect(); Console.WriteLine("Induced a collection."); }

public static void WaitForFullGCProc() { while (true) { // CheckForNotify is set to true and false in Main. while (checkForNotify) { // Check for a notification of an approaching collection. GCNotificationStatus s = GC.WaitForFullGCApproach(); if (s == GCNotificationStatus.Succeeded) { Console.WriteLine("GC Notifiction raised."); OnFullGCApproachNotify(); } else if (s == GCNotificationStatus.Canceled) { Console.WriteLine("GC Notification cancelled."); break; } else { // This can occur if a timeout period is specified for // WaitForFullGCApproach(Timeout) or WaitForFullGCComplete(Timeout) // and the time out period has elapsed. Console.WriteLine("GC Notification not applicable."); break; }

Profiler

Why would you need to use a Weak Event handler? Take a look at this example of normal events and handlers:

Notice how the Console window is empty. The Subscriber finalizer ~Subscriber() which writes to the console window has not been called meaning our subscriber is still in memory. This is due to the Publisher event holding a strong reference to the Subscribers event handler (see the watch window).

Why not just implement IDispose and unsubscribe from the event?

This is the ideal scenario but you are relying upon our Publisher being considerate enough to call dispose on the Subscriber. This means we can remove the event handler, notice how the publishers event is now null, which means the GarbageCollector can collect our subscriber.

But what happens if the Publisher forgets to “dispose” of the subscriber? We still have a memory leak.

Weak Reference Events to the rescue!

We can see here in the watch window that the publishers event still has a reference to the subscribers event handler. But the subscriber has been disposed…. cool!