E
Edward K Ream
Hello all. I'm tracking down memory leaks in my app. To do this I wrote a
script to show the numbers of each different type of object. But it doesn't
show strings! Here is the script:
import gc,types
def printDict(d):
keys = d.keys() ; keys.sort()
print '-' * 30
for key in keys:
n = d.get(key)
print '%+6d %s' % (n,key)
d = {} ; d2 = {}
for obj in gc.get_objects():
t = type(obj)
r = repr(t)
n = d.get(r,0)
d[r] = n + 1
if t == types.InstanceType:
t = obj.__class__
r = repr(t)
n = d2.get(r,0)
d2[r] = n + 1
printDict(d)
printDict(d2)
And here is example output. The first part of the listing shows the 'raw'
type of each object, the second part of the listing shows
type(obj.__class__) for instance types.
------------------------------
+1925 <class 'leoGlobals.Bunch'>
+1 <class 'leoNodes.nodeIndices'>
+47 <class 'leoNodes.position'>
+2858 <class 'leoNodes.tnode'>
+2877 <class 'leoNodes.vnode'>
+1 <class 'random.Random'>
+1 <class 'site._Helper'>
+3 <class 'site._Printer'>
+1 <class 'string._TemplateMetaclass'>
+1 <class 'threading._Condition'>
+1 <class 'threading._MainThread'>
+1 <class 'unittest.TestLoader'>
+536 <type 'builtin_function_or_method'>
+27 <type 'cell'>
+1 <type 'classmethod'>
+1 <type 'classmethod_descriptor'>
+538 <type 'classobj'>
+11942 <type 'dict'>
+14 <type 'frame'>
+8493 <type 'function'>
+3 <type 'generator'>
+70 <type 'getset_descriptor'>
+1997 <type 'instance'>
+3704 <type 'instancemethod'>
+4441 <type 'list'>
+72 <type 'member_descriptor'>
+226 <type 'method_descriptor'>
+181 <type 'module'>
+1 <type 'property'>
+29740 <type 'tuple'>
+1 <type 'tupleiterator'>
+53 <type 'type'>
+105 <type 'weakref'>
+362 <type 'wrapper_descriptor'>
------------------------------
+1 <class Pmw.Pmw_1_2.lib.PmwLoader.PmwLoader at 0x0156D390>
+1 <class Tkinter.BitmapImage at 0x0154E5D0>
+30 <class Tkinter.Button at 0x0154E270>
+1 <class Tkinter.CallWrapper at 0x0154E030>
+5 <class Tkinter.Canvas at 0x0154E2A0>
+9 <class Tkinter.Checkbutton at 0x0154E2D0>
+1 <class Tkinter.Event at 0x01540EA0>
+51 <class Tkinter.Frame at 0x0154E330>
+15 <class Tkinter.IntVar at 0x01540F30>
+11 <class Tkinter.Label at 0x0154E360>
+3 <class Tkinter.Listbox at 0x0154E390>
+61 <class Tkinter.Menu at 0x0154E3C0>
+7 <class Tkinter.PhotoImage at 0x0154E5A0>
+3 <class Tkinter.Radiobutton at 0x0154E450>
+19 <class Tkinter.Scrollbar at 0x0154E4B0>
+5 <class Tkinter.StringVar at 0x01540F00>
+1 <class Tkinter.Tk at 0x0154E0C0>
+9 <class Tkinter.Toplevel at 0x0154E240>
+6 <class _Pmw.Pmw_1_2.lib.PmwBalloon.Balloon at 0x0186D870>
+1545 <class _Pmw.Pmw_1_2.lib.PmwBase.__TkinterCallWrapper at 0x015A66F0>
+2 <class _Pmw.Pmw_1_2.lib.PmwNoteBook.NoteBook at 0x0162ECF0>
+1 <class _Pmw.Pmw_1_2.lib.PmwPanedWidget.PanedWidget at 0x016FA360>
+2 <class _Pmw.Pmw_1_2.lib.PmwScrolledFrame.ScrolledFrame at 0x016FADE0>
+3 <class __future__._Feature at 0x00EB6840>
+2 <class compiler.misc.Set at 0x00E899C0>
+1 <class compiler.pyassem.StackDepthTracker at 0x00E89B10>
+3 <class doctest.DocTestParser at 0x00EE50C0>
+2 <class encodings.cp1252.Codec at 0x00ADE1E0>
+2 <class encodings.cp437.Codec at 0x00CF0AE0>
+1 <class exceptions.MemoryError at 0x00A87120>
+1 <class leoApp.LeoApp at 0x00BAF930>
+3 <class leoAtFile.atFile at 0x00DBF180>
+3 <class leoChapters.chapter at 0x015D6660>
+1 <class leoChapters.chapterController at 0x015D6630>
+1 <class leoColor.colorizer at 0x00CCA8A0>
+2 <class leoColor.nullColorizer at 0x00CCA8D0>
+3 <class leoCommands.Commands at 0x00FE1900>
+3 <class leoCommands.configSettings at 0x00FE1930>
+1 <class leoConfig.configClass at 0x00CF03C0>
+1 <class leoConfig.settingsTreeParser at 0x00CF03F0>
+1 <class leoEditCommands.AspellClass at 0x00F20E40>
+3 <class leoEditCommands.abbrevCommandsClass at 0x00F15810>
+3 <class leoEditCommands.bufferCommandsClass at 0x00F20B10>
+3 <class leoEditCommands.controlCommandsClass at 0x00F20B40>
+3 <class leoEditCommands.debugCommandsClass at 0x00F20B70>
+3 <class leoEditCommands.editCommandsClass at 0x00F20BA0>
+3 <class leoEditCommands.editFileCommandsClass at 0x00F20BD0>
+3 <class leoEditCommands.helpCommandsClass at 0x00F20C00>
+3 <class leoEditCommands.keyHandlerCommandsClass at 0x00F20C30>
+3 <class leoEditCommands.killBufferCommandsClass at 0x00F20C60>
+3 <class leoEditCommands.leoCommandsClass at 0x00F20C90>
+3 <class leoEditCommands.macroCommandsClass at 0x00F20CC0>
+3 <class leoEditCommands.queryReplaceCommandsClass at 0x00F20CF0>
+3 <class leoEditCommands.rectangleCommandsClass at 0x00F20D20>
+3 <class leoEditCommands.registerCommandsClass at 0x00F20D50>
+3 <class leoEditCommands.searchCommandsClass at 0x00F20DB0>
+3 <class leoEditCommands.spellCommandsClass at 0x00F20DE0>
+1 <class leoEditCommands.spellTabHandler at 0x00F20E10>
+3 <class leoFileCommands.fileCommands at 0x00F932D0>
+3 <class leoFind.leoFind at 0x00C12840>
+5 <class leoFind.searchWidget at 0x00C12810>
+2 <class leoFrame.nullBody at 0x00CF0210>
+2 <class leoFrame.nullFrame at 0x00CF0240>
+2 <class leoFrame.nullIconBarClass at 0x00CF0270>
+2 <class leoFrame.nullLog at 0x00CF02A0>
+2 <class leoFrame.nullTree at 0x00CF0300>
+6 <class leoFrame.stringTextWidget at 0x00CF00F0>
+2 <class leoGlobals.redirectClass at 0x00BAF420>
+2 <class leoGui.nullGui at 0x00CF0330>
+3 <class leoImport.leoImportCommands at 0x00F93FC0>
+3 <class leoKeys.autoCompleterClass at 0x00E70720>
+3 <class leoKeys.classScannerClass at 0x00E70600>
+3 <class leoKeys.forgivingParserClass at 0x00E705D0>
+2 <class leoKeys.keyHandlerClass at 0x00E707B0>
+2 <class leoMenu.nullMenu at 0x00CDDCC0>
+3 <class leoTangle.tangleCommands at 0x00FE1750>
+1 <class leoTkinterFind.tkFindTab at 0x015AF630>
+1 <class leoTkinterFind.tkSpellTab at 0x015AF660>
+12 <class leoTkinterFind.underlinedTkButton at 0x015AF5D0>
+20 <class leoTkinterFrame.leoTkTextWidget at 0x016006F0>
+1 <class leoTkinterFrame.leoTkinterBody at 0x016005D0>
+1 <class leoTkinterFrame.leoTkinterFrame at 0x01600660>
+1 <class leoTkinterFrame.leoTkinterLog at 0x01600690>
+1 <class leoTkinterFrame.leoTkinterTreeTab at 0x016006C0>
+1 <class leoTkinterFrame.tkIconBarClass at 0x01600630>
+1 <class leoTkinterFrame.tkStatusLineClass at 0x01600600>
+1 <class leoTkinterGui.leoKeyEvent at 0x015B77B0>
+1 <class leoTkinterGui.tkinterGui at 0x01600720>
+1 <class leoTkinterKeys.tkinterKeyHandlerClass at 0x016FA990>
+1 <class leoTkinterMenu.leoTkinterMenu at 0x015DB150>
+3 <class leoTkinterTree.leoTkinterTree at 0x016004E0>
+3 <class leoUndo.undoer at 0x00CF0090>
+1 <class mod_scripting.scriptingController at 0x0162E060>
+1 <class nav_buttons.imageClass at 0x0162E990>
+1 <class nav_buttons.marksDialog at 0x0162E9C0>
+1 <class nav_buttons.recentSectionsDialog at 0x0162EA20>
+1 <class os._Environ at 0x00A9BC30>
+5 <class plugins_menu.PlugIn at 0x01540270>
+1 <class plugins_menu._PluginDatabase at 0x01527B40>
+2 <class repr.Repr at 0x00EDB690>
+10 <class tkFont.Font at 0x015DB120>
+2 <class xml.sax.handler.ErrorHandler at 0x00F75360>
I get similar results on both Python 2.4 and Python 2.5. I'm running on XP.
Can anyone explain were the strings are? I expect at least twice the number
of strings as there are leoNodes.vnode objects.
Edward
script to show the numbers of each different type of object. But it doesn't
show strings! Here is the script:
import gc,types
def printDict(d):
keys = d.keys() ; keys.sort()
print '-' * 30
for key in keys:
n = d.get(key)
print '%+6d %s' % (n,key)
d = {} ; d2 = {}
for obj in gc.get_objects():
t = type(obj)
r = repr(t)
n = d.get(r,0)
d[r] = n + 1
if t == types.InstanceType:
t = obj.__class__
r = repr(t)
n = d2.get(r,0)
d2[r] = n + 1
printDict(d)
printDict(d2)
And here is example output. The first part of the listing shows the 'raw'
type of each object, the second part of the listing shows
type(obj.__class__) for instance types.
------------------------------
+1925 <class 'leoGlobals.Bunch'>
+1 <class 'leoNodes.nodeIndices'>
+47 <class 'leoNodes.position'>
+2858 <class 'leoNodes.tnode'>
+2877 <class 'leoNodes.vnode'>
+1 <class 'random.Random'>
+1 <class 'site._Helper'>
+3 <class 'site._Printer'>
+1 <class 'string._TemplateMetaclass'>
+1 <class 'threading._Condition'>
+1 <class 'threading._MainThread'>
+1 <class 'unittest.TestLoader'>
+536 <type 'builtin_function_or_method'>
+27 <type 'cell'>
+1 <type 'classmethod'>
+1 <type 'classmethod_descriptor'>
+538 <type 'classobj'>
+11942 <type 'dict'>
+14 <type 'frame'>
+8493 <type 'function'>
+3 <type 'generator'>
+70 <type 'getset_descriptor'>
+1997 <type 'instance'>
+3704 <type 'instancemethod'>
+4441 <type 'list'>
+72 <type 'member_descriptor'>
+226 <type 'method_descriptor'>
+181 <type 'module'>
+1 <type 'property'>
+29740 <type 'tuple'>
+1 <type 'tupleiterator'>
+53 <type 'type'>
+105 <type 'weakref'>
+362 <type 'wrapper_descriptor'>
------------------------------
+1 <class Pmw.Pmw_1_2.lib.PmwLoader.PmwLoader at 0x0156D390>
+1 <class Tkinter.BitmapImage at 0x0154E5D0>
+30 <class Tkinter.Button at 0x0154E270>
+1 <class Tkinter.CallWrapper at 0x0154E030>
+5 <class Tkinter.Canvas at 0x0154E2A0>
+9 <class Tkinter.Checkbutton at 0x0154E2D0>
+1 <class Tkinter.Event at 0x01540EA0>
+51 <class Tkinter.Frame at 0x0154E330>
+15 <class Tkinter.IntVar at 0x01540F30>
+11 <class Tkinter.Label at 0x0154E360>
+3 <class Tkinter.Listbox at 0x0154E390>
+61 <class Tkinter.Menu at 0x0154E3C0>
+7 <class Tkinter.PhotoImage at 0x0154E5A0>
+3 <class Tkinter.Radiobutton at 0x0154E450>
+19 <class Tkinter.Scrollbar at 0x0154E4B0>
+5 <class Tkinter.StringVar at 0x01540F00>
+1 <class Tkinter.Tk at 0x0154E0C0>
+9 <class Tkinter.Toplevel at 0x0154E240>
+6 <class _Pmw.Pmw_1_2.lib.PmwBalloon.Balloon at 0x0186D870>
+1545 <class _Pmw.Pmw_1_2.lib.PmwBase.__TkinterCallWrapper at 0x015A66F0>
+2 <class _Pmw.Pmw_1_2.lib.PmwNoteBook.NoteBook at 0x0162ECF0>
+1 <class _Pmw.Pmw_1_2.lib.PmwPanedWidget.PanedWidget at 0x016FA360>
+2 <class _Pmw.Pmw_1_2.lib.PmwScrolledFrame.ScrolledFrame at 0x016FADE0>
+3 <class __future__._Feature at 0x00EB6840>
+2 <class compiler.misc.Set at 0x00E899C0>
+1 <class compiler.pyassem.StackDepthTracker at 0x00E89B10>
+3 <class doctest.DocTestParser at 0x00EE50C0>
+2 <class encodings.cp1252.Codec at 0x00ADE1E0>
+2 <class encodings.cp437.Codec at 0x00CF0AE0>
+1 <class exceptions.MemoryError at 0x00A87120>
+1 <class leoApp.LeoApp at 0x00BAF930>
+3 <class leoAtFile.atFile at 0x00DBF180>
+3 <class leoChapters.chapter at 0x015D6660>
+1 <class leoChapters.chapterController at 0x015D6630>
+1 <class leoColor.colorizer at 0x00CCA8A0>
+2 <class leoColor.nullColorizer at 0x00CCA8D0>
+3 <class leoCommands.Commands at 0x00FE1900>
+3 <class leoCommands.configSettings at 0x00FE1930>
+1 <class leoConfig.configClass at 0x00CF03C0>
+1 <class leoConfig.settingsTreeParser at 0x00CF03F0>
+1 <class leoEditCommands.AspellClass at 0x00F20E40>
+3 <class leoEditCommands.abbrevCommandsClass at 0x00F15810>
+3 <class leoEditCommands.bufferCommandsClass at 0x00F20B10>
+3 <class leoEditCommands.controlCommandsClass at 0x00F20B40>
+3 <class leoEditCommands.debugCommandsClass at 0x00F20B70>
+3 <class leoEditCommands.editCommandsClass at 0x00F20BA0>
+3 <class leoEditCommands.editFileCommandsClass at 0x00F20BD0>
+3 <class leoEditCommands.helpCommandsClass at 0x00F20C00>
+3 <class leoEditCommands.keyHandlerCommandsClass at 0x00F20C30>
+3 <class leoEditCommands.killBufferCommandsClass at 0x00F20C60>
+3 <class leoEditCommands.leoCommandsClass at 0x00F20C90>
+3 <class leoEditCommands.macroCommandsClass at 0x00F20CC0>
+3 <class leoEditCommands.queryReplaceCommandsClass at 0x00F20CF0>
+3 <class leoEditCommands.rectangleCommandsClass at 0x00F20D20>
+3 <class leoEditCommands.registerCommandsClass at 0x00F20D50>
+3 <class leoEditCommands.searchCommandsClass at 0x00F20DB0>
+3 <class leoEditCommands.spellCommandsClass at 0x00F20DE0>
+1 <class leoEditCommands.spellTabHandler at 0x00F20E10>
+3 <class leoFileCommands.fileCommands at 0x00F932D0>
+3 <class leoFind.leoFind at 0x00C12840>
+5 <class leoFind.searchWidget at 0x00C12810>
+2 <class leoFrame.nullBody at 0x00CF0210>
+2 <class leoFrame.nullFrame at 0x00CF0240>
+2 <class leoFrame.nullIconBarClass at 0x00CF0270>
+2 <class leoFrame.nullLog at 0x00CF02A0>
+2 <class leoFrame.nullTree at 0x00CF0300>
+6 <class leoFrame.stringTextWidget at 0x00CF00F0>
+2 <class leoGlobals.redirectClass at 0x00BAF420>
+2 <class leoGui.nullGui at 0x00CF0330>
+3 <class leoImport.leoImportCommands at 0x00F93FC0>
+3 <class leoKeys.autoCompleterClass at 0x00E70720>
+3 <class leoKeys.classScannerClass at 0x00E70600>
+3 <class leoKeys.forgivingParserClass at 0x00E705D0>
+2 <class leoKeys.keyHandlerClass at 0x00E707B0>
+2 <class leoMenu.nullMenu at 0x00CDDCC0>
+3 <class leoTangle.tangleCommands at 0x00FE1750>
+1 <class leoTkinterFind.tkFindTab at 0x015AF630>
+1 <class leoTkinterFind.tkSpellTab at 0x015AF660>
+12 <class leoTkinterFind.underlinedTkButton at 0x015AF5D0>
+20 <class leoTkinterFrame.leoTkTextWidget at 0x016006F0>
+1 <class leoTkinterFrame.leoTkinterBody at 0x016005D0>
+1 <class leoTkinterFrame.leoTkinterFrame at 0x01600660>
+1 <class leoTkinterFrame.leoTkinterLog at 0x01600690>
+1 <class leoTkinterFrame.leoTkinterTreeTab at 0x016006C0>
+1 <class leoTkinterFrame.tkIconBarClass at 0x01600630>
+1 <class leoTkinterFrame.tkStatusLineClass at 0x01600600>
+1 <class leoTkinterGui.leoKeyEvent at 0x015B77B0>
+1 <class leoTkinterGui.tkinterGui at 0x01600720>
+1 <class leoTkinterKeys.tkinterKeyHandlerClass at 0x016FA990>
+1 <class leoTkinterMenu.leoTkinterMenu at 0x015DB150>
+3 <class leoTkinterTree.leoTkinterTree at 0x016004E0>
+3 <class leoUndo.undoer at 0x00CF0090>
+1 <class mod_scripting.scriptingController at 0x0162E060>
+1 <class nav_buttons.imageClass at 0x0162E990>
+1 <class nav_buttons.marksDialog at 0x0162E9C0>
+1 <class nav_buttons.recentSectionsDialog at 0x0162EA20>
+1 <class os._Environ at 0x00A9BC30>
+5 <class plugins_menu.PlugIn at 0x01540270>
+1 <class plugins_menu._PluginDatabase at 0x01527B40>
+2 <class repr.Repr at 0x00EDB690>
+10 <class tkFont.Font at 0x015DB120>
+2 <class xml.sax.handler.ErrorHandler at 0x00F75360>
I get similar results on both Python 2.4 and Python 2.5. I'm running on XP.
Can anyone explain were the strings are? I expect at least twice the number
of strings as there are leoNodes.vnode objects.
Edward