Logzone

A Logging Hook for Zone

Version 0.9

R Stephan


Description / Where To Get Logzone

Swarm is a Java/Objective-C framework for agent based modelling (ABM). logzone is a set of Obj-C classes to facilitate monitoring of Zones in Swarm applications and performing operations necessary for leak detection. While a C leak detector library like `efence' contains hooks for the free/malloc functions, logzone, from this perspective, is a hook for Zone, the main memory building block in Obj-C Swarm models.

Logzone is available from the swarm.org archive or from the author's website.

Installation

The package comes as a gzipped tar archive file.

  1. To unpack, issue the tar xvfz command on the package. A subdirectory named `logzone-version' should be filled.
  2. cd into the created directory.
  3. With make, the file `liblogzone.a' should be built.
  4. As root, do make install. The library and header files are copied into your Swarm installation directory.
  5. The library is linked into your programs by putting -llogzone into your `Makefile' APPLIBS variable, e.g. APPLIBS=-llogzone

Logzone Usage / Search Strategy

One of the many delights of programming is the moment that you notice your running program takes more and more memory you cannot account for. Garbage collection works around this problem but this option is (at this time) not available for Objective-C Swarm modeling. This is where leak detectors have proved helpful.

Logzone comes into play when you suspect that in your Swarm model allocated objects are not freed -- for example because you notice your Obj-C program eats more and more memory.

First, you import the included logzone header file:

#import <logzone.h>

We assume now you have designed your model memory usage by giving globalZone, or one or several freshly made Zones to your classes' creation routines; this would be standard Swarm policy. Then you can monitor your classes of interest by substituting the relevant Zone with a LoggingZone by giving it as argument to create instead of your usual Zone. The common situation would be that you have a ModelSwarm or BatchSwarm that contains all your classes, at least indirectly: then just create it with a LoggingZone. Here is a schema of the process:

+-------------------+      +-----------+    +---------------+
|SwarmObject::create|----->|LoggingZone|====| KISSMemLogger |--> GUI
|SwarmObject::drop  |....  +-----------+    +---------------+
+-------------------+   .        |          +----------------+
        |  |            .        |          | ASCIIMemLogger |-> File
+-------------------+   .     +--v---+      +----------------+
| AnObject::create  |   .....>| Zone |      +------------+
| AnObject::drop    |         +------+      | RMemLogger |-----> R
+-------------------+                       +------------+

Your objects invisibly send the create message to their superclass until the SwarmObject superclass gets it and invokes the Zone functions. The LoggingZone sends all requests to the Zone class but does bookkeeping on objects and classes. This information can then be output in several ways.

The implemented bookkeeping mechanisms are quite simple and depend on the MemLogConsumer your LoggingZone is bound to. The default, the KISSMemLogger, is a GUI window showing the classes that take the most memory in the Zone at the top (KISS stands for `Keep It Simple stupid').

If, armed with this info, you still cannot see any objects responsible for the leak, then the other possibility is that the leaks are created within globalZone or scratchZone -- especially the latter ones, e.g. temporary indices, are frequently overlooked. There is one caveat with respect to scratchZone: this case can only be safely handled if you use an ASCIIMemLogger with your LoggingZone, see section MemLogConsumers: Available Output Formats. The section section Examples shows how to do it.

There is no limit on the number of LoggingZones. I used logzone to debug itself, for example, by giving a second LoggingZone to a first LoggingZone as creation argument; the first would be monitoring a model. I would then get two windows with my happily running model -- one monitoring the model, the other monitoring the monitor!

MemLogConsumers: Available Output Formats

Each LoggingZone refers to a protocol named MemLogConsumer for sending its output to, and you can substitute your own classes provided they conform to this protocol (protocols are for Obj-C what interfaces are for Java). The logzone library provides you with several ready-made MemLogConsumers, and the usage of them all is treated in section Examples.

Examples

Each of the examples assumes the header file is included, and both logzone and logger are temporary ids. We always use an ObserverSwarm to monitor.

#import <logzone.h>
...
  id logzone, logger;

The default behaviour is to give you sorted cumulative info in a graphics window.

logzone = [LoggingZone create: globalZone];
observerSwarm = [AquariumObserverSwarm create: logzone];

You can also send alloc info (non-cumulative) to a file/`stdout'.

logzone = [LoggingZone createBegin: globalZone];
[logzone setAsciiFilename: 0]; // to stdout
logzone = [logzone createEnd];
observerSwarm = [AquariumObserverSwarm create: logzone];

It is also possible to set a refined logger, e.g. log cumulative info separated by commata to a file named `testlog'

logzone = [LoggingZone createBegin: globalZone];
logger = [AsciiMemLogger createBegin: globalZone];
[logger setCumulative];
[logger setFilename: "testlog"];
[logger setRecordDelim: "\n" dataDelim: ","];
logger = [logger createEnd];
[logzone setMemLogConsumer: logger];
logzone = [logzone createEnd];
observerSwarm = [AquariumObserverSwarm create: logzone];

One can even log scratchZone/globalZone by replacing it with a LoggingZone.

logzone = [LoggingZone createBegin: globalZone];
[logzone setAsciiFilename: 0]; // to stdout
// WARNING: using a different logger may result in infinite loops.
scratchZone = [logzone createEnd];

The RMemLogger can be used to log single (de)allocation events or per step.

logzone = [LoggingZone createBegin: globalZone];
logger = [RMemLogger createBegin: globalZone];
[logger setCumulative];
[logger setFilename: "rlog"];
logger = [logger createEnd];
[logzone setMemLogConsumer: logger];
logzone = [logzone createEnd];
observerSwarm = [AquariumObserverSwarm create: logzone];

The resulting file `rlog' could then be read from within R with something like:

frame <- read.table("rlog",header=TRUE)

Logging in other formats (contributions!) or more graphically sophisticated would be nice to have.

Discussion of KISSMemLogger's Bookkeeping

In this section we try to justify some internal design choices. Specifically, we want to address the points made by Marcus G. Daniels on one of the Swarm mailing lists on the efficency of the combination of algorithms used in the KISSMemLogger class. The conclusion to be drawn is that there are no complexity reasons for chosing an algorithm based on AVL trees.

To summarize the working of KISSMemLogger, a hashtable holds the current number of existing objects of a class, and this information is sorted and printed on the screen every step. Now MGD points out that it could be faster to use an AVL tree as container since sorting then isn't necessary anymore. Let's look at the potential savings more closely.

Let M be the average number of allocations plus deallocations during a timestep, and N the number of classes to be shown in the output of the GUI window (this can be reduced by removing entries of classes that have currently no objects allocated). Let f(M,N) be the time complexity of the current bookkeeping algorithm, and g(M,N) the one for the algorithm using AVL trees. Then f(M,N)=O(N log N)+M*O(1) whereas g(M,N)=M*O(log N).

Clearly, both functions have the same complexity. One can even say, although general Swarm usage certainly spans all situations including M<<N and M>>N, the novice and intermediate user has models where M is about or greater than N, and only comparisons of specific implementations can bring more light into the question of efficiency. We would expect time savings from AVL trees only when M<<N.

Analyzing With awk

Here is an example of an awk script to cumulate alloc info from the (default non-cumulative) ASCII output.

BEGIN { arr[0]=0 }
{
  if ( $3 in arr )
  {
    if ( $2 ~ /\+/ ) 
      arr[$3] = arr[$3]+1 
    else 
      arr[$3] = arr[$3]-1
  }
  else
  {
    if ( $2 ~ /\+/ ) 
      arr[$3] = 1
  }
}
END { for ( i in arr ) print i,arr[i] }

Patches

Please send patches to Ralf Stephan. Thanks for your contribution.

Logzone Copying Conditions

The programs currently being distributed that relate to logzone consist of the included source code. These programs are free; this means that everyone is free to use them and free to redistribute them on a free basis furtherly detailed.

The logzone-related programs are not in the public domain; they are copyrighted and there are restrictions on their distribution, but these restrictions are designed to permit everything that a good cooperating citizen would want to do. What is not allowed is to try to prevent others from further sharing any version of these programs that they might get from you.

Specifically, we want to make sure that you have the right to give away copies of the programs that relate to logzone, that you receive source code or else can get it if you want it, that you can change these programs or use pieces of them in new free programs, and that you know you can do these things.

To make sure that everyone has such rights, we have to forbid you to deprive anyone else of these rights. For example, if you distribute copies of the Texinfo related programs, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. Also, for our own protection, we must make certain that everyone finds out that there is no warranty for the programs that relate to logzone. If these programs are modified by someone else and passed on, we want their recipients to know that what they have is not what we distributed, so that any problems introduced by others will not reflect on our reputation.

The precise conditions of the licenses for the programs currently being distributed that relate to logzone are found in the General Public Licenses that accompany them.


This document was generated on 10 August 2000 using texi2html 1.56k.