Share via


Introducing ObjectGraphLibrary to visualize Stack and Heap

In this post I'm going to share a custom implementation of classes which can be used to visualize two important parts of memory i.e Stack and Heap.

Introduction

Purpose of ObjectGraphLibrary is to visualize two important memory parts of a process i.e. Stack and Heap. Visualizing memory of a process is much helpful for novice user. Many visualizers have been developed so far to help novices in learning computer execution model and unfortunately no such tool exits either in Windows Phone or in Windows Store on any programming language . Programs of novices are tiny in memory footprint and respective entire memory can easily be visualized so ObjectGraphLibrary is going to present all the available information in memory that is helpful for learning purposes. Before going to implement ObjectGraphLibrary let's discuss important.

  • Visualizer

    Visualizer is a framework of different components that can swap depending on what structure is currently being visualized. It keeps the tracks of different structure in memory, takes care of each structure and decides what data structure will be displayed on user interaction and on what particular location.

  • Stack

    Stack is the regions of memory where data is added or removed in a last-in-first-out manner. In most modern computer systems, each thread has a reserved region of memory referred to as its stack. When a function executes, it may add some of its state data to the top of the stack; when the function exits it is responsible for removing that data from the stack. At a minimum, a thread's stack is used to store the location of function calls in order to allow return statements to return to the correct location, but programmers may further choose to explicitly use the stack. If a region of memory lies on the thread's stack, that memory is said to have been allocated on the stack.

  • Heap

    Stack is the regions of memory where data is added or removed in a last-in-first-out manner. In most modern computer systems, each thread has a reserved region of memory referred to as its stack. When a function executes, it may add some of its state data to the top of the stack; when the function exits it is responsible for removing that data from the stack. At a minimum, a thread's stack is used to store the location of function calls in order to allow return statements to return to the correct location, but programmers may further choose to explicitly use the stack. If a region of memory lies on the thread's stack, that memory is said to have been allocated on the stack.

  • Stack Frame

    A stack frame is a frame of data that gets pushed onto the stack. A stack frame represent a function call and its argument data. The function return address goes on the stack first, then the arguments and space for local variables, and together they make the "frame".

  • Heap Object

    An object that allocate memory area in heap. Heap objects first memory bit address is the address of heap object. However we will use a unique integer to repesent its address so called here "UniqueId"

Implementation

ObjectGraphLibrary implementation contains representation of both Stack and Heap object and their associated objects. Some general data type for collection, dictionary, value object and heap object reference are also implemented in ObjectModel.

Summary of all the the class exist in namespace ObjectGraphLibrary.ObjectModel is given below:

Name Type Description
VisualObjectType Enum Type of Visual Object
IVisualObject Interface Represents any object that can be visualized
VisualObject Class Represent visualize-able object
CollectionObject Class Reprsenet collection of IVisualObject
DictionaryObject Class Represent Dictionary of Visual Objects
ReferenceObject Class Represent Referance to heap object
ObservableHeap Class Represent entire heap
ObservableHeapFrame Class Represent closely related Heap objects
ObservableHeapFrameItem Class Represent a heap object
ObservableStack Class Represent an entire stack
ObservableStackFrame Class Represent a Stack Frame
ObservableStackFrameItem Class Represent a variable/local inside stack frame

Almost against each data type there exist an User Interface class in namespace ObjectGraphLibrary.UI.Xaml. Each UI class has it's own style defined in Themes/Generic.xaml. Main UI class is ObjectGraphPresenter that is the actual layout class responsible for visualization. Structurly ObjectGraphPresenter can be divided into three parts. Stack, Heap and Connectors. Stack is arranged in left side of ObjectGraphPresenter whereas heap is arranged in right side ObjectGraphPresenter. Connectors overly stack and heap and connects a heap pointer to the pointed heap object. Connectors are further divided into two parts 1. Stack Connector 2. Heap Connector. Stack connector connects heap pointer from stack region and target heap object. Heap connectors connects heap pointers inside a heap object and the targeted heap object.

Structure of ObjectGraphPresenter is explained in below image.

Drawing Connector Lines

Connector lines are BezierSegment placed in PathFigure. To draw a connector first of all we have to search for heap reference in each stack frame. If any heap reference is found next we have to get it's visual container using ItemsControl.ContainerFromItem. Using similar code we can get container for target heap object after searching target object in the heap.

To find position of containers relative to parent grid UIElement.TransformToVisual is handy. Using previous command we can calculate the position of container from origion of parent grid. This calculated position is in negative coordinates. Using Math.Abs position coordinates are converted to signed double. Calculated point is exact position left-top corner of an element relative to parent grid. A BezierSegment with start point of stack container right-bottom corner position and end point of target heap object left-top corner position is added to PathGeomtry. This way we can draw connector lines between stack and heap.

Using similar logic we can draw heap connectors too.

When to draw Connectors

We knows how to draw connectors but question is when to draw connectors?. If we update connectors with each LayoutUpdate then this lead to circular layout update call. According to MSDN FrameworkElemet.LayoutUpdated is call each time there is a change in visual tree. When an update to visual tree is made we draw connector that also updates the visual tree and leading to circular layout update. If we handle it once then layout is partially updated and some items UI container is null.

If we update connectors on change in items then particular item is not rendered so we can get its position in grid. So, we need a middle way and the way is to set itemUpdated = true when item changes. And in LayoutUpdate handle if itemUpdated is true then en-queue a task to perform when in idle state on Dispatcher. And after completly updating the UI Dispatcher will be idle and executes our task that will render the connectors.

bool itemChanged = false;
protected override void OnItemsChanged(object e)
{
     itemChanged = true;
     base.OnItemsChanged(e);
}
 
public event EventHandler ItemUpdated;
 
void OnItemUpdated()
{
     if (ItemUpdated != null)
         ItemUpdated(this, EventArgs.Empty);
}
 
private void OnLayoutUpdated(object sender, object e)
{
    if (itemChanged)
        this.Dispatcher.RunIdleAsync(FireItemUpdated);
}
 
private void FireItemUpdated(IdleDispatchedHandlerArgs e)
{
    OnItemUpdated();
    itemChanged = false;
}

Visual Object Rendering

Visualizer decides what data structure will be displayed and how. DataTemplate is a way to define different templates for different data structures. All the objects in Stack has same template however heap objects requires some attention. For every heap data structure a data template is defined. HeapFrameItemTemplateSelector decides which data structure will be displayed in which way.

Object Graph Library Demo is action

Using Library

A working demo project is added with the project. To embed it in your project, first you have to add reference to "ObjectGraphLibray" project. Where you want to to render add a ContentPresenter their and name it as "GraphPresenter". Open C# file and first include add below code on the top of file

using ObjectGraphLibrary;
using ObjectGraphLibrary.ObjectModel;
using ObjectGraphLibrary.UI.Xaml;
Add this code where you actually want to load the user interface. It can be in constructor, load event handler or button click handler etc.
 
ObservableStack stack;
ObservableHeap heap;
JsonConverter.Deserialize(jsonText, out stack, out heap);
var graph = new ObjectGraphPresenter { Stack= stack, Heap = heap };
GraphPresenter.Content = graph;

Where "jsonText" is the json string in the format as explained below

Json Format

Json root object contains two keys Stack and Heap. Type of Stack is array and each item in Stack array will represent a Stack Frame.Each Stack Frame has two keys Label and Items. Label is the Header show on Stack Frame and Items is the array of variables in Stack Frame. Each variable in "Items" contains two field Label and Value. Label field on each variable is the name of variable and is show on left side in StackFrameItem. Value field of variable is complicated and is discussed at the end. Second key in Json root is "Heap" of type object that contains heap items against that particular heap item unique id represented as string. Value of heap item is same as stack frame variable value.

Stack Frame Variable Value and Heap Item Value both has same format. Any type of value is assigned to heap item value i.e number, Boolean, string, null, array, object. However stack frame variable value doesn't support array and object. To refer item in heap a special case-sensitive string of format "REF-XX" is used, where XX is the unique id of heap item

Sample Json

{
  "Stack": [
        {
            "Label": "Globals",
            "Items": [
                {
                    "Label": "sample_list",
                    "Value": "REF-1"
                },
                {
                    "Label": "filter_marks",
                    "Value": "REF-2"
                }
            ]
        },
        {
            "Label": "filter_marks",
            "Items": [
                {
                    "Label": "lst",
                    "Value": "REF-1"
                },
                {
                    "Label": "integers",
                    "Value": "REF-3"
                },
                {
                    "Label": "strings",
                    "Value": "REF-4"
                },
                {
                    "Label": "element",
                    "Value": "Huzaifah"
                }
            ]
        }
    ],
    "Heap": {
        "1": [
            25,
            "Huzaifah",
            38,
            "Adnan",
            54,
            "Abdul Rehman"
        ],
        "2" : "filter_marks(lst)",
        "3" : [
            25
        ],
        "4" : [
            "Huzaifah"
        ]
    }
}

Source Code and Demo Project

Download complete source code from here http://gallery.technet.microsoft.com/Object-Graph-Library-to-0d110ece/

It contains entire source code of ObjectGraphLibrary and a demo project to test the library. If you have any question feel free to comment below or contact me at u.adnan@outlook.com. Follow me @u.adnan