diff --git a/fsl/__init__.py b/fsl/__init__.py
index 5613aec3f6abe8cc23c3494f00b4405b75a38727..790be29422ef1af2b4dcada525dd11ca6022e4da 100644
--- a/fsl/__init__.py
+++ b/fsl/__init__.py
@@ -59,28 +59,41 @@ import argparse
 import subprocess
 
 
-log = logging.getLogger(__name__)
-
-
 # make matplotlib quiet
 warnings.filterwarnings('ignore', module='matplotlib')
 warnings.filterwarnings('ignore', module='mpl_toolkits')
 
+# My own custom logging level for tracing memory related events
+logging.MEMORY = 15
+def logmemory(self, message, *args, **kwargs):
+    if self.isEnabledFor(logging.MEMORY):
+        self._log(logging.MEMORY, message, args, **kwargs)
+        
+logging.Logger.memory = logmemory
+logging.addLevelName(logging.MEMORY, 'MEMORY')
+
 
 # There's a bug in OpenGL.GL.shaders (which has been fixed in
 # the latest version) - it calls logging.basicConfig(), and
 # thus screws up our own logging. We overcome this by configuring
 # the root logger before OpenGL.GL.shaders is imported (which
 # occurs when fsl.fslview.gl.slicecanvas.SliceCanvas is imported).
-logging.basicConfig(
-    format='%(levelname)8.8s '
-           '%(filename)20.20s '
-           '%(lineno)4d: '
-           '%(funcName)-15.15s - '
-           '%(message)s') 
+
+logFormatter = logging.Formatter('%(levelname)8.8s '
+                                 '%(filename)20.20s '
+                                 '%(lineno)4d: '
+                                 '%(funcName)-15.15s - '
+                                 '%(message)s')
+logHandler  = logging.StreamHandler()
+logHandler.setFormatter(logFormatter)
+
+
 log = logging.getLogger('fsl')
 
 
+log.addHandler(logHandler)
+
+
 import fsl.tools as tools
 
 
@@ -176,6 +189,10 @@ def parseArgs(argv, allTools):
     parser.add_argument(
         '-n', '--noisy', metavar='MODULE', action='append',
         help='Make the specified module noisy')
+
+    parser.add_argument(
+        '-m', '--memory', action='store_true',
+        help='Output memory events (implied if -v is set)')
     
     parser.add_argument(
         '-w', '--wxinspect', action='store_true',
@@ -242,12 +259,23 @@ def parseArgs(argv, allTools):
 
     # Configure any logging verbosity 
     # settings specified by the user
+    if namespace.verbose is None:
+        if namespace.memory:
+            class MemFilter(object):
+                def filter(self, record):
+                    if record.levelno == logging.MEMORY: return 1
+                    else:                                return 0
+
+            log.setLevel(logging.MEMORY)
+            log.handlers[0].addFilter(MemFilter())
+            log.memory('Added filter for MEMORY messages')
+        
     if namespace.verbose == 1:
         log.setLevel(logging.DEBUG)
 
         # make some noisy things quiet
-        logging.getLogger('fsl.fslview.gl')   .setLevel(logging.WARNING)
-        logging.getLogger('fsl.fslview.views').setLevel(logging.WARNING)
+        logging.getLogger('fsl.fslview.gl')   .setLevel(logging.MEMORY)
+        logging.getLogger('fsl.fslview.views').setLevel(logging.MEMORY)
         logging.getLogger('props')            .setLevel(logging.WARNING)
         logging.getLogger('pwidgets')         .setLevel(logging.WARNING)
     elif namespace.verbose == 2:
diff --git a/fsl/data/image.py b/fsl/data/image.py
index cb4bdf27a57e403a0e253ba9e5bf401695f0c67b..f27dfdb404a63b25ddad4bdd7e43fc52ea17fcd8 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -168,6 +168,12 @@ class Image(props.HasProperties):
         if len(self.shape) < 3 or len(self.shape) > 4:
             raise RuntimeError('Only 3D or 4D images are supported')
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
+
+        
+    def __del__(self):
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+        
         
     def loadData(self):
         """Loads the image data from the file. This method only needs to
diff --git a/fsl/data/model.py b/fsl/data/model.py
index d286c65720542b81a1d0a7bc4cecea4bcb51aea2..542ed38d65a4ad900823f198ca304d1ae417b056 100644
--- a/fsl/data/model.py
+++ b/fsl/data/model.py
@@ -5,9 +5,15 @@
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
 
+import logging
+
 import os.path as op
 import numpy   as np
 
+
+log = logging.getLogger(__name__)
+
+
 ALLOWED_EXTENSIONS     = ['.vtk']
 EXTENSION_DESCRIPTIONS = ['VTK polygon model file']
 
@@ -78,6 +84,12 @@ class Model(object):
         self.vertices = np.array(data, dtype=np.float32)
         self.indices  = indices
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
+
+        
+    def __del__(self):
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+        
 
     def __repr__(self):
         return '{}({}, {})'.format(type(self).__name__,
diff --git a/fsl/fslview/displaycontext/display.py b/fsl/fslview/displaycontext/display.py
index 4d930bd3131f35ebcc6a4ed3c6b073e33e47efd4..bb38e7af0f61dd21b9a76039c2bb94438c8ae6eb 100644
--- a/fsl/fslview/displaycontext/display.py
+++ b/fsl/fslview/displaycontext/display.py
@@ -47,6 +47,12 @@ class DisplayOpts(props.SyncableHasProperties):
         self.overlayType = display.overlayType
         self.name        = '{}_{}'.format(type(self).__name__, id(self))
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
+
+        
+    def __del__(self):
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+
         
     def destroy(self):
         """If overridden, this method should be called by the subclass
@@ -200,7 +206,12 @@ class Display(props.SyncableHasProperties):
         self.__displayOpts = None
         self.__overlayTypeChanged()
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
 
+        
+    def __del__(self):
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+        
 
     def destroy(self):
         """This method should be called when this ``Display`` instance
diff --git a/fsl/fslview/gl/globject.py b/fsl/fslview/gl/globject.py
index ce1463265bd4a0a8cc69cd4c0b663ddc06fb4d45..6a143bd43ed33bb0813b54cf5e8b8991f5ff2b8a 100644
--- a/fsl/fslview/gl/globject.py
+++ b/fsl/fslview/gl/globject.py
@@ -12,6 +12,7 @@ mappings between overlay objects and their corresponding OpenGL
 representation.
 """
 
+import logging
 
 import numpy as np
 
@@ -19,6 +20,9 @@ import routines            as glroutines
 import fsl.utils.transform as transform
 
 
+log = logging.getLogger(__name__)
+
+
 def createGLObject(overlay, display):
     """Create :class:`GLObject` instance for the given overlay, as specified
     by the :attr:`.Display.overlayType` property.
@@ -73,7 +77,7 @@ class GLObject(object):
         self.zax  = 2
         
         self.__updateListeners = {}
-        
+
         
     def addUpdateListener(self, name, listener):
         """Adds a listener function which will be called whenever this
@@ -225,6 +229,12 @@ class GLImageObject(GLObject):
         self.display     = display
         self.displayOpts = display.getDisplayOpts()
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
+
+        
+    def __del__(self):
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+        
 
     def destroy(self):
         """If this method is overridden, it should be called by the subclass