Skip to Content Java Solaris Communities Partners My Sun Sun Store United States Worldwide

»  Spotlight Articles
»  Projects
»  Publications
»  People
»  Awards
»  Events
»  Downloads
»  Internships
»  Contrarian Minds
»  About Sun Labs

Introduction: What Is GCspy?

GCspy is a heap visualisation framework. It is designed to visualise a wide variety of memory management systems, whether they are managed by a garbage collector or implement explicit deallocation. Its target users are mainly memory management implementers and it allows them to observe the behaviour of their system. GCspy is not limited to small toy systems; it can also visualise loads of realistic sizes, and do so dynamically, as the system operates. However, if the user needs it, a trace storing and replaying facility is also available.

What Can GCspy Visualise?

Even though it was designed for memory management, GCspy can in fact visualise any system that is made up of a number of components (this number should be low, say 1-5) and each component can be subdivided into smaller partitions (these can range from a handful to thousands; you are only limited by the screen size and memory of your workstation). For example, in a generational memory management system, each generation can be seen as a component and, for visualisation purposes, can be subdivided into equal-size memory blocks. Alternatively, using the same framework, GCspy can also visualise the free list 'component' of the memory system, assuming that a generation adopts an in-place deallocation policy; in this case, each subdivision is a single free list.

Architecture

A client-server architecture was adopted for GCspy; the system that is being visualised is the server and the visualisation GUI is the client; they communicate through standard sockets. This architecture has several advantages: only the least possible amount of code is added to the system being visualised, the client can be run on another machine to affect the operation of the server as little as possible, and the client can be connected to and disconnected from the server when necessary. Additionally, only the server side of GCspy needs to be adopted for a particular system. At connection-time, the server sends bootstrap information to the client that describes its structure and layout. Then, the client adjusts itself for that particular server and starts accepting visualisation transmissions.

In order to visualise a system, the implementer has to write a GCspy driver for each of its components. A driver is a module that maps the operation and layout of a component onto the generic GCspy abstractions: spaces, which represent components, and streams, which represent a component's attributes. A driver is customised for a particular system and component.

Click on it for a larger version

The above figure illustrates the architecture of GCspy, when incorporated into a Java[tm] Virtual Machine. It is assumed that the virtual machine has a generational memory system with two generations and each generation is managed by a different garbage collector (Semi-Spaces or S-S for the young generation and Mark&Compact or M&C for the old generation). The illustration shows that, in order to visualise this memory system, two GCspy drivers need to be implemented, one per garbage collector.

The colors in the figure indicate the following:

  • Blue. The original ("vanilla") virtual machine.
  • Green. The generic GCspy framework that is re-used whichever system GCspy is incorporated into. Notice that the whole of the client is green.
  • Red. The only parts of the server that need to be customised for a particular system. These include the two drivers and a thin layer of code inside the virtual machine that collects the state of the garbage collectors and communicates it to the drivers.
In the current implementation of GCspy, the client is written entirely in Java using Swing, but there are three implementations of the server infrastructure, in Java, C, and C++, for incorporation into systems written in those languages.

Sample Screenshots

Click on it for a larger version

The above screenshot shows GCspy visualising Sun's Java HotSpot[tm] virtual machine running the SPECjvm98 _213_javac benchmark. Its memory management adopts a generational framework with three distinct components (or spaces in GCspy terminology): the young generation (where most newly-allocated objects are allocated), the old generation (where longer-lived objects are eventually promoted to), and the permanent space (where "permament" objects like classes, methods, etc. are allocated). Each space is split into 16K blocks, each of which is represented by a tile on the screen. The screenshot shows how full each space is (bright red tiles represent memory blocks that are full of objects). The state of the system reflected on the screenshot is at the end of a young generation collection (this is indicated by the text field at the top left of the window); this is why the young generation is relatively empty. Finally, the large text area on the left of the window gives detailed information about the selected tile (highlighted with a white frame, roughly in the middle of the old generation).

Click on it for a larger version

The above screenshot was taken at exactly the same time as the previous one, however the views have changed to represent the number of objects per memory block (the brighter the tile is, the more objects the corresponding block has). One thing we can immediately notice is that the old generation seems "brighter" overall compared to the permanent space; this is because the objects in the permanent space tend to be larger, hence each block has a smaller number of them. Additionally, in this screenshot, a tile in the young generation is selected; notice that the information provided in the text area on the left is different from that of the previous screenshot (GCspy doesn't assume that all components will have the same attributes as, in most cases, they don't).

History Graphs

The screenshots in the previous section show the state of the heap at a single point in time. It is also extremely interesting to be able to observe the behaviour of the visualised system over a period of time. This is the purpose of the history graphs that GCspy can generate. Each history graph is a grid of very small squares and represents the behaviour of a single attribute of the component over time. Each horizontal line of this grid represents a single transmission (this usually corresponds to an event in the server) and each vertical line represents the state change of a single component subdivision (e.g. a memory block) over time. The color of each square reflects the value of the attribute being visualised (e.g. bright when the value is high). Every time a new transmission takes place, a new horizontal line is appended at the end of the graph. According to this, the y-axis essentially represents time.

Click on it for a larger version

The above history graph was taken from a single run of the SPECjvm98 _213_javac benchmark running on Sun's Java HotSpot virtual machine. It shows how full the old generation is over time. The horizontal white lines represent old generation collections. The red area in the graph is the used space in the generation (and remember: time moves downwards). Notice how the generation fills up, as time passes by, and then empties immediately after each old generation collection.

Click on it for a larger version

This second history graph was taken at the same time as the first one, however it shows which areas of the old generation contain references that point to the young generation (a light gray color indicates that there are no such references; a black color indicates that there are a few such references; a bright color indicates that there are many such references). First notice that the colors are mainly gray and black; this is because no memory block contains more than a few references to young objects. Additionally, notice that black squares are scattered around the graph and there seems to be a large number of them. Usually, generational memory systems assume a small number of old-to-young references; this is not the case here. The last observation that can be made from this graph, when comparing it to the previous one, is that objects newly-promoted in the generation (e.g. the ones that are on the edge of the red area in the previous graph), seem to have references to young objects; this is indicated by the black line in the bottom graph that matches the edge of the red area in the top graph.

GCspy-Related Publications

  • T. Printezis and A. Garthwaite. Visualising the Train Garbage Collector. In D. Detlefs, editor, Proceedings of the 2002 International Symposium on Memory Management, pages 50-63, Berlin, Germany, July 2002. ps pdf
  • T. Printezis and R. E. Jones. GCspy: An Adaptable Heap Visualisation Framework. In S. Matsuoka, editor, Proceedings of the 17th Annual ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA 2002), Seattle, WA, November 2002. ps pdf

History

GCspy was initially developed by Tony Printezis, while at the Computing Science Department of the University of Glasgow in Scotland under a collaborative research agreement with Sun Microsystems Laboratories, and in collaboration with Richard Jones of the Computer Science Department at the University of Kent at Canterbury.

Contact Information

If you would like to learn more about GCspy, please contact Tony Printezis (tony.printezis@sun.com) at SunLabs East.
Would you recommend this Sun site to a friend or colleague?
Contact About Sun News Employment Privacy Terms of Use Trademarks Copyright 1994-2008 Sun Microsystems, Inc.