diff --git a/Control/HeapMon/HeapMon/HeapMon.h b/Control/HeapMon/HeapMon/HeapMon.h
new file mode 100644
index 0000000000000000000000000000000000000000..0687a82a800024b26bc6407a03b4423a69778837
--- /dev/null
+++ b/Control/HeapMon/HeapMon/HeapMon.h
@@ -0,0 +1,44 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef HEAPMON_HEAPMON_H
+#define HEAPMON_HEAPMON_H
+
+#if defined(__linux__)
+
+#define _GNU_SOURCE 1
+
+#include <stdio.h>
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+
+#endif
+
+#include "Python.h"
+
+/* control parameters for static data blocks */
+
+/* maximum available number of check points */
+#define mm_MAX_CHECKPOINTS          10
+
+/* start size of hash tables for data */
+#define mm_HASHTABLE_MINSIZE      4096
+
+/* maximum total depth of tracebacks kept in memory */
+#define mm_TRACEDEPTH       12
+/* system offset: 0 == helper, 1 == hook, 2 == malloc/realloc */
+#define mm_SYSTEMOFF         3
+/* total backtrace size left: mm_TRACEDEPTH - mm_SYSTEMOFF */
+#define mm_BACKTRACE_SIZE   mm_TRACEDEPTH - mm_SYSTEMOFF
+
+/* max size for symbols, files, and other buffers */
+#define mm_SYMBOL_BUFLEN          2048
+
+#endif /* !HEAPMON_HEAPMON_H */
diff --git a/Control/HeapMon/cmt/fragments/python_extension b/Control/HeapMon/cmt/fragments/python_extension
new file mode 100644
index 0000000000000000000000000000000000000000..696fd1b7850af048dd712cc17664e2a52d523a8a
--- /dev/null
+++ b/Control/HeapMon/cmt/fragments/python_extension
@@ -0,0 +1,46 @@
+# File: HeapMon/cmt/fragments/python_extension
+# Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
+
+# Build a python extension module (i.e. shared lib w/o 'lib' prepend) and
+# install it into InstallArea/python/<Package>/. Note that the full build is
+# done here, rather than through CMT processing, as it's sooo much faster.
+
+.PHONY: ${CONSTITUENT} ${CONSTITUENT}clean
+
+#allfiles := $(wildcard ${FILEPATH}*.cxx)
+#objects  := ${allfiles:${FILEPATH}%.cxx=$(bin)%.o}
+#allcfiles := $(wildcard ${FILEPATH}${files})
+allcfiles := $(wildcard ${FILEPATH}*.c)
+cobjects := ${allcfiles:${FILEPATH}%.c=$(bin)%.o}
+# installd := ${CMTINSTALLAREA}/$(tag)/lib/python$(Python_config_version_twodigit)/${package}
+installd := ${CMTINSTALLAREA}/python/${package}/$(tag)
+pyextlib := ${installd}/${CONSTITUENT}.$(shlibsuffix)
+
+${CONSTITUENT} :: $(bin)${CONSTITUENT}.$(shlibsuffix) ${pyextlib}
+
+${objects} : $(bin)%.o : ${FILEPATH}%.cxx
+	$(cpp_echo) $@
+	$(cpp_silent) cd $(bin); $(cppcomp) -o $@ $(use_pp_cppflags) $(${CONSTITUENT}_pp_cppflags) $(app_${CONSTITUENT}_pp_cppflags) $(use_cppflags) $(${CONSTITUENT}_cppflags) $(app_${CONSTITUENT}_cppflags) ${ADDINCLUDE} $<
+
+${cobjects} : $(bin)%.o : ${FILEPATH}%.c
+	$(c_echo) $@
+	$(c_silent) cd $(bin); $(ccomp) -o $@ $(use_pp_cflags) $(${CONSTITUENT}_pp_cflags) $(app_${CONSTITUENT}_pp_cflags) $(use_cflags) $(${CONSTITUENT}_cflags) $(app_${CONSTITUENT}_cflags) ${ADDINCLUDE} $<
+
+# explicitly linked with almost nothing (typically, $(use_linkopts) will be needed)
+$(bin)${CONSTITUENT}.$(shlibsuffix): ${objects} ${cobjects}
+ifeq (${objects},)
+	$(lib_silent) cd $(bin); $(link) $(shlibflags) ${cobjects:$(bin)%.o=%.o} $(${CONSTITUENT}_linkopts) -o ${CONSTITUENT}.$(shlibsuffix)
+else
+	$(lib_silent) cd $(bin); $(cpplink) $(shlibflags) ${objects:$(bin)%.o=%.o} ${cobjects:$(bin)%.o=%.o} $(${CONSTITUENT}_linkopts) -o ${CONSTITUENT}.$(shlibsuffix)
+endif
+
+${installd} :
+	@mkdir -p ${installd}
+
+# hack: gmake on lxplus (1.79.1) does not support order only targets nor realpath
+${pyextlib} : $(bin)${CONSTITUENT}.$(shlibsuffix) ${installd}
+	@cd $(bin); test -f $(pyextlib) || ln -s `pwd`/${CONSTITUENT}.$(shlibsuffix) $(pyextlib)
+
+${CONSTITUENT}clean ::
+	$(cleanup_echo) objects
+	$(cleanup_silent) /bin/rm -f ${objects} $(bin)${CONSTITUENT}.$(shlibsuffix) ${pyextlib}
diff --git a/Control/HeapMon/cmt/fragments/python_extension_header b/Control/HeapMon/cmt/fragments/python_extension_header
new file mode 100644
index 0000000000000000000000000000000000000000..fce7b79071760841e096a4b2dfb1126fd229a944
--- /dev/null
+++ b/Control/HeapMon/cmt/fragments/python_extension_header
@@ -0,0 +1,4 @@
+# File: HeapMon/cmt/fragments/python_extension_header
+# Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
+
+# this file is left empty on purpose
diff --git a/Control/HeapMon/cmt/requirements b/Control/HeapMon/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..a306d1e1484806188296720c9024b1fe083589f9
--- /dev/null
+++ b/Control/HeapMon/cmt/requirements
@@ -0,0 +1,52 @@
+package HeapMon
+
+author Mous Tatarkhanov <tmmous@berkeley.edu>
+
+use AtlasPolicy      AtlasPolicy-*
+use AtlasPython      AtlasPython-*     External
+use AtlasGPerfTools  AtlasGPerfTools-* External
+#use GaudiInterface 	GaudiInterface-* 	External
+
+private
+use AtlasROOT   		AtlasROOT-*   		External
+end_private
+
+application MemoryScanner MemoryScanner.cxx
+
+#apply_pattern component_library
+
+# the memory marker relies on gcc (tag gcc is set in ExternalPolicy, which
+# comes in from AtlasPolicy) internals: only build on that platform (there
+# will be a warning on other platforms, but we don't have any others right
+# now, so no worries :) )
+
+# although "gcc" as tag should do, that doesn't work on gcc344 (even as the
+# tag is defined according to "cmt show all_tags"), so use Linux (works, as
+# empirically determined :P )
+macro python_extension_fragment "" \
+   Linux "python_extension -dependencies -header=python_extension_header" \
+   Darwin "python_extension -dependencies -header=python_extension_header"
+make_fragment $(python_extension_fragment)
+       
+# hack: empty document will be ignored; anything else doesn't work with CMT
+document python_extension MemoryMarker files="*.c" MemoryMarker.c
+
+# force order between installing header files and build of .c files
+macro_append MemoryMarker_dependencies " install_includes "
+
+# libraries for retrieving debug info
+macro_append MemoryMarker_linkopts "" \
+  use_bfd                          " -aarchive -L/usr/local/lib -L/usr/lib -lbfd -liberty "
+
+macro_append cflags "" \
+   use_bfd                          " -DHEPHAESTUS_USE_BFD "
+
+# install python module files (actually, the .so is done in the fragment)
+apply_pattern declare_python_modules files="*.py"
+
+
+private
+
+# always use new ABI and force optimization, even in debug mode
+macro_append cppflags " -fuse-cxa-atexit "
+macro_append cflags " -O3 "
diff --git a/Control/HeapMon/python/EventNotifier.py b/Control/HeapMon/python/EventNotifier.py
new file mode 100644
index 0000000000000000000000000000000000000000..53efc4fa3491bb64b432c4bbcd798157492989f4
--- /dev/null
+++ b/Control/HeapMon/python/EventNotifier.py
@@ -0,0 +1,147 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+import AthenaPython.PyAthena as PyAthena
+import sys, os
+
+from ROOT import TTree, TFile
+from array import array
+
+
+#from HeapMon import MemoryScanner as memscanner
+#from HeapMon import MemoryMarker as memmarker
+#from Hephaestus import MemoryTracker as memtracker
+
+
+class EventExecutionNotifier( PyAthena.Alg ):
+    event_number = 0
+    max_events = 0
+    stop_scan  = 1
+    start_scan = 0
+    report_scan_number = 0
+    file_name = "heapmon.freed.root"
+    marker = 0xCD
+    
+    memmarker = 'HeapMon.MemoryMarker' in sys.modules and sys.modules[ 'HeapMon.MemoryMarker' ] or None 
+    memscanner = 'HeapMon.MemoryScanner' in sys.modules and sys.modules[ 'HeapMon.MemoryScanner' ] or None
+    memtracker = 'Hephaestus.MemoryTracker' in sys.modules and sys.modules[ 'Hephaestus.MemoryTracker' ] or None
+
+    #memtracker = 'Hephaestus.MemoryTracker' in sys.modules and \
+    #   sys.modules['Hephaestus.MemoryTracker' ] or None
+    
+    def __init__(self, name="EventExecutionNotifier"):
+        ## init the base class
+        super(EventExecutionNotifier,self).__init__()        
+        return
+
+    def initialize( self ):        
+    # INITIALIZATION MARKING    
+        print 'Notifier.initialize():'
+        #memmarker = 'HeapMon.MemoryMarker' in sys.modules and \
+        #sys.modules[ 'HeapMon.MemoryMarker' ] or None        
+        #if memmarker:
+        #    memmarker.start()        
+        
+        self.event_number = 0
+        
+        print "    file_name = ", self.file_name
+        print "    self.max_events = ", self.max_events    
+        print "    report_scan_number = ", self.report_scan_number 
+        if self.memtracker:
+            print('    starting memtracker - MemoryTracker ')
+            self.memtracker.start()
+        else:
+            print('    memtracker - MemoryTracker not loaded!')
+
+        if self.memscanner:
+            #print'    memscanner.memscan()'
+            self.memscanner.memscan(self.file_name, 2, self.event_number, self.marker); #SCAN_FLAG = 2: no holes statistics saved, just info
+        else:
+            print('    memscanner is not loaded!')   
+            
+    # Extract MallocInfo and put into root file    
+        self.mallinfo()
+        return PyAthena.StatusCode.Success
+    
+    def execute( self ):
+        print "Notifier.execute()"        
+        self.event_number +=1 
+        print "Notifier.event_number = ", self.event_number
+        
+        if self.memscanner:
+            print '    memscanner.memscan()'                
+            if   (self.start_scan == 0):
+                    self.memscanner.memscan(self.file_name, 2, self.event_number, self.marker); #SCAN_FLAG = 1:  holes statistics saved
+            elif (self.start_scan == -1):
+                    self.memscanner.memscan(self.file_name, 1, self.event_number, self.marker); #SCAN_FLAG = 2: no holes statistics saved, just info
+            elif ((self.event_number >= self.start_scan) 
+                    and (self.event_number <= self.stop_scan)):
+                       self.memscanner.memscan(self.file_name, 1, self.event_number, self.marker); #SCAN_FLAG = 2: no holes statistics saved, just info
+            else:
+                    self.memscanner.memscan(self.file_name, 2, self.event_number, self.marker); #SCAN_FLAG = 1:  holes statistics saved
+        else:
+            print('    memscanner is not loaded!')
+        
+        
+        self.mallinfo()
+        
+        if self.memtracker:
+            if self.event_number <= self.stop_scan:
+                print ('MemoryTracker is marking the memory')
+            else:
+                print("MemoryTracker configure() to stop the marking");
+                print ("MemoryTracker.gFlags = ",
+                    self.memtracker.configure(
+                        self.memtracker.LEAK_CHECK | 
+                        self.memtracker.QUICK )#| MemoryTracker.FILTER_STL)
+                    )
+        elif self.memmarker:
+            if (self.start_scan == 0):
+                print('EventNotifier.execute(): marker idling')      
+            elif self.event_number <= self.stop_scan:
+                    print 'EventNotifier.execute(): memmarker.start(), event_number=', self.event_number
+                    self.memmarker.start() 
+            else:
+                print('Notifier.execute(): MemoryMarker.stop() , event_number=', self.event_number)
+                self.memmarker.stop()
+        else:
+            print('Notifier.execute(): memmarker and memtracker are not loaded!')
+
+        return PyAthena.StatusCode.Success
+        
+    def finalize( self ):
+        self.msg.info( 'finalizing [%s]', self.name() )
+        if self.memmarker:
+            self.memmarker.stop()
+        if self.memtracker:
+            self.memtracker.stop()
+        if self.memscanner:
+            from HeapMon import HeapMonReport as memreport
+            memreport.report()
+        return PyAthena.StatusCode.Success
+
+
+    def mallinfo(self):   
+        if self.memmarker:
+            print('Notifier.mallinfo(): malloc info') 
+            (malloc_sbrk, malloc_mmap, malloc_inuse, malloc_free) = self.memmarker.get_malloc_info()
+            sbrk =  array('I', [0]); sbrk[0] = malloc_sbrk;
+            mmap =  array('I', [0]); mmap[0] = malloc_mmap;
+            inuse = array('I', [0]); inuse[0] = malloc_inuse;
+            free =  array('I', [0]); free[0] = malloc_free;
+            print 'sbrk=', sbrk, ' mmap=', mmap, ' inuse=', inuse, 'free', free
+            scan_number = array('L', [0]); scan_number[0] = self.event_number;
+            memFile = TFile(self.file_name, "update")
+            mallocTree = memFile.Get("mallocTree");
+            mallocTree.SetBranchAddress("malloc_sbrk", sbrk);
+            mallocTree.SetBranchAddress("malloc_mmap", mmap);
+            mallocTree.SetBranchAddress("malloc_inuse",inuse);
+            mallocTree.SetBranchAddress("malloc_free", free);
+            mallocTree.SetBranchAddress("scan_number", scan_number);
+            mallocTree.Fill()
+            mallocTree.Write()
+            mallocTree.Delete
+            memFile.Write()
+            memFile.Close()
+            self.memmarker.show_info()
+        else:
+            print('Notifier.mallinfo(): memmarker is not loaded!')
diff --git a/Control/HeapMon/python/HeapMonReport.py b/Control/HeapMon/python/HeapMonReport.py
new file mode 100644
index 0000000000000000000000000000000000000000..af1af67d2a50ec6a65ec8cdb24eb1354397f0bc5
--- /dev/null
+++ b/Control/HeapMon/python/HeapMonReport.py
@@ -0,0 +1,309 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+import AthenaPython.PyAthena as PyAthena
+import sys, os
+import math, time   , array
+
+from ROOT import gROOT, gDirectory, gStyle, gPad
+from ROOT import TFile
+from ROOT import TH1I, TH2I, TF1
+from ROOT import TH1F, TH2F, TGraph, TMultiGraph
+from ROOT import TCanvas, TPad, TPaveLabel, TPaveText, TLegend
+
+#from ROOT import TCanvas # available at startup
+root_file = 'mems.root'  
+freed_file = 'heapmon.freed.root'
+
+hole_trace_start = 0
+
+def iReport(file):
+    global root_file
+    root_file = file
+    report()
+
+def pReport():
+    global root_file    
+    memscanner = 'HeapMon.MemoryScanner' in sys.modules and \
+    sys.modules[ 'HeapMon.MemoryScanner' ] or None    
+    if memscanner:
+        holes_file = memscanner.freescan_output
+    #root_file = file
+    report()
+
+def findStaticHoles():
+    global freed_file
+    global hole_trace_start     
+    tfile = TFile(freed_file, "READ")
+    
+    #mychain = gDirectory.Get( 'memTree' )    
+    tree = tfile.Get("holeTree")
+    entry_number = tree.GetEntries()
+    print("There are ", entry_number , " entries in ", root_file)
+    previous_scan_number = -1;
+    
+    holes_dict = dict()
+    previous_holes_dict = dict()
+
+    for i in xrange(entry_number):
+        tree.GetEntry(i)
+        if tree.scan_number < hole_trace_start:
+            continue
+        if previous_scan_number == tree.scan_number:
+            #print "add new hole ", tree.hole_start, "size ", tree.hole_size
+            holes_dict[tree.hole_start] = tree.hole_size;
+        else:
+            previous_scan_number = tree.scan_number
+            if previous_holes_dict:
+                print "looking for intersection with next scan dict"
+                intersection = dict([(item,holes_dict[item]) for item in holes_dict.keys() if previous_holes_dict.has_key(item)])
+                previous_holes_dict = intersection
+                print len(intersection), " elements in intersection"
+                #print "intersection=", intersection
+            else:
+                previous_holes_dict = holes_dict                
+            
+            holes_dict.clear()
+    
+    intersection = dict([(item,holes_dict[item]) for item in holes_dict.keys() if previous_holes_dict.has_key(item)])
+    
+    print "intersection=", intersection
+    print len(intersection), " static holes identified"
+    
+    import cPickle
+    pickle_file = "mems.dat"
+    file = open(pickle_file, 'w')
+    cPickle.dump(intersection, file)
+    file.close()    
+    del file
+    
+
+def report():
+    global freed_file
+    print'    HeapMonReport.report(): heapmon_file=', freed_file
+    
+    #findStaticHoles()
+          
+    tfile = TFile(freed_file, "READ")
+    print "   root compression factor = ", tfile.GetCompressionFactor()
+   
+    mem_canvas = TCanvas("HeapMon_report", "Memory Holes Statistics", 10, 10, 800, 1034);
+    mem_canvas.SetFillColor(17);
+    mem_canvas.cd()
+    
+    pad1 = TPad("pad1","pad1",0.01,0.57,0.50,0.93,33);
+    pad2 = TPad("pad2","pad2",0.51,0.57,0.99,0.93,33);
+    pad3 = TPad("pad3","pad3",0.01,0.01,0.99,0.50,33);
+    pad3.SetPhi(210);
+    pad3.SetTheta(25);
+
+    pad1.Draw(); pad2.Draw(); pad3.Draw();
+    memTree = tfile.Get("holeTree")
+    infoTree = tfile.Get("infoTree")
+    mallocTree = tfile.Get("mallocTree")
+    #holesm_th1i =   TH1I('holesm_th1i', 'Holes size evolution', fcount, 0, fcount)    
+    #holesn_th1i =   TH1I('holesn_th1i', 'Holes number evolution', fcount, 0, fcount)  
+    #total_th1i  =   TH1I('total_th1i', 'Total memory size evolution', fcount, 0, fcount)
+    
+    max_hole_size = memTree.GetMaximum("hole_size")
+    print "    max_hole_size=", max_hole_size, "    min_hole_size", memTree.GetMinimum("hole_size")
+    max_scan_number = memTree.GetMaximum("scan_number")
+    print "     max_scan_number=", max_scan_number
+    
+    memHist1  = TH2I("mem2d","Hole-sizes distribution evolution", 128, -0.5, max_hole_size - 0.5, 50, 0, max_scan_number) 
+    memTree.Project("mem2d", "scan_number:hole_size"); 
+    
+    multiGraph1 = TMultiGraph();
+    multiGraph2 = TMultiGraph();
+
+    print " memHist.GetMaximum() = ",    memHist1.GetMaximum();
+    
+    # Working on a Report
+    gStyle.SetOptStat(0);
+    gStyle.SetPalette(1);
+    gStyle.SetCanvasColor(33);
+    gStyle.SetFrameFillColor(18);
+    
+    memHist1.SetFillColor(30);
+    memHist1.SetFillStyle(0);
+    memHist1.GetXaxis().SetTitle("Size of holes, kb");
+    memHist1.GetXaxis().SetLabelOffset(0.02);
+    memHist1.GetXaxis().SetLabelSize(0.02);
+    memHist1.GetXaxis().SetTitleSize(0.04);
+    memHist1.GetXaxis().SetTitleColor(2);
+    memHist1.GetYaxis().SetTitle("Event number");
+    memHist1.GetYaxis().SetLabelSize(0.04);
+    memHist1.GetXaxis().SetLabelOffset(0.04);
+    memHist1.GetYaxis().SetTitleSize(0.04);
+    memHist1.GetYaxis().SetTitleColor(2);
+    memHist1.GetZaxis().SetTitle("Number of holes");
+    memHist1.GetZaxis().SetLabelSize(0.02);
+    memHist1.GetZaxis().SetTitleSize(0.04);
+    memHist1.GetZaxis().SetTitleColor(2);
+    
+    title = TPaveLabel(0.1,0.95,0.9,0.99, "Job Memory Usage Plots");
+    title.SetFillColor(42);
+    title.SetTextFont(42);
+    title.Draw();
+    
+    text_box = TPaveText(0.1,0.51,0.9,0.54);
+    text_box.AddText("Malloc freed ('marked') Heap Memory Profile");
+    text_box.SetFillColor(42);
+    text_box.SetTextAlign(12);
+    text_box.SetTextFont(42);
+    text_box.Draw();
+    
+    x1=0.2; y1=0.91; x2=0.8; y2=0.98;
+
+#Drawing upper-left corner Pad1 of the report
+    pad1.cd();
+    pad1.SetGridx();pad1.SetGridy();
+    infoTree.Draw("total_maps_memory:scan_number","", "goff")
+    mapsGraph=TGraph(int(infoTree.GetSelectedRows()), infoTree.GetV2(), infoTree.GetV1());    
+    mapsGraph.SetLineColor(1); mapsGraph.SetLineWidth(1); #mapsGraph.SetFillStyle(3001); mapsGraph.SetFillColor(2);
+    mapsGraph.SetName("total_maps_memory");
+    #VmSize, VmLck, VmRSS, VmData, VmStk, VmExe, VmLib;
+    infoTree.Draw("VmSize:scan_number", "","goff"); 
+    vmsizeGraph=TGraph(int(infoTree.GetSelectedRows()), infoTree.GetV2(), infoTree.GetV1());    
+    vmsizeGraph.SetLineColor(2); vmsizeGraph.SetLineWidth(1); #vmsizeGraph.SetFillStyle(3002); vmsizeGraph.SetFillColor(3);
+    vmsizeGraph.SetName("VmSize");
+    
+    infoTree.Draw("VmRSS:scan_number", "", "goff"); 
+    vmrssGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmrssGraph.SetLineColor(3); vmrssGraph.SetLineWidth(1); #vmrssGraph.SetFillStyle(3003); vmrssGraph.SetFillColor(4);
+    vmrssGraph.SetName("VmRSS"); 
+    
+    infoTree.Draw("VmData:scan_number", "", "goff"); 
+    vmdataGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmdataGraph.SetLineColor(4); vmdataGraph.SetLineWidth(1); #vmdataGraph.SetFillStyle(3004); vmdataGraph.SetFillColor(4);
+    vmdataGraph.SetName("VmData"); 
+    
+    infoTree.Draw("VmStk:scan_number", "", "goff"); 
+    vmstkGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmstkGraph.SetLineColor(5); vmstkGraph.SetLineWidth(1); #vmstkGraph.SetFillStyle(3005); vmstkGraph.SetFillColor(4);
+    vmstkGraph.SetName("VmStk")
+    
+    infoTree.Draw("VmExe:scan_number", "", "goff"); 
+    vmexeGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmexeGraph.SetLineColor(6); vmexeGraph.SetLineWidth(1); #vmexeGraph.SetFillStyle(3003); vmexeGraph.SetFillColor(4);
+    vmexeGraph.SetName("VmExe");
+    
+    infoTree.Draw("VmLib:scan_number", "", "goff"); 
+    vmlibGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmlibGraph.SetLineColor(7); vmlibGraph.SetLineWidth(1); #vmlibGraph.SetFillStyle(3003); vmlibGraph.SetFillColor(4);
+    vmlibGraph.SetName("VmLib");
+  
+    infoTree.Draw("VmLck:scan_number", "", "goff"); 
+    vmlckGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1());
+    vmlckGraph.SetLineColor(8); vmlckGraph.SetLineWidth(1); #vmlckGraph.SetFillStyle(3003); vmlckGraph.SetFillColor(4);
+    vmlckGraph.SetName("VmLck");
+
+    infoTree.Draw("total_hole_memory:scan_number", "", "goff");
+    holeGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1())    
+    holeGraph.SetLineColor(9); holeGraph.SetLineWidth(1); #holeGraph.SetFillStyle(3004); holeGraph.SetFillColor(5);
+    holeGraph.SetName("HolesSize"); 
+        
+    mallocTree.Draw("malloc_free:scan_number", "", "goff"); 
+    freeGraph=TGraph(mallocTree.GetSelectedRows(), mallocTree.GetV2(), mallocTree.GetV1())    
+    freeGraph.SetLineColor(11); freeGraph.SetLineWidth(1); freeGraph.SetFillStyle(3003); freeGraph.SetFillColor(4);
+    freeGraph.SetName("malloc_free");
+    
+    mallocTree.Draw("malloc_inuse:scan_number", "", "goff"); 
+    inuseGraph=TGraph(mallocTree.GetSelectedRows(), mallocTree.GetV2(), mallocTree.GetV1())    
+    inuseGraph.SetLineColor(21); inuseGraph.SetLineWidth(1); inuseGraph.SetFillStyle(3003); inuseGraph.SetFillColor(4);
+    inuseGraph.SetName("malloc_inuse");
+
+    mallocTree.Draw("malloc_sbrk:scan_number", "", "goff"); 
+    sbrkGraph=TGraph(mallocTree.GetSelectedRows(), mallocTree.GetV2(), mallocTree.GetV1())    
+    sbrkGraph.SetLineColor(31); sbrkGraph.SetLineWidth(1); sbrkGraph.SetFillStyle(3003); sbrkGraph.SetFillColor(4);
+    sbrkGraph.SetName("malloc_sbrk");
+    
+    mallocTree.Draw("malloc_mmap:scan_number", "", "goff"); 
+    mmapGraph=TGraph(mallocTree.GetSelectedRows(), mallocTree.GetV2(), mallocTree.GetV1())    
+    mmapGraph.SetLineColor(41); mmapGraph.SetLineWidth(1); mmapGraph.SetFillStyle(3003); mmapGraph.SetFillColor(4);
+    mmapGraph.SetName("malloc_mmap");
+    
+    pad1.cd();
+    multiGraph1.Add(mapsGraph);multiGraph1.Add(vmsizeGraph);
+    multiGraph1.Add(vmrssGraph);multiGraph1.Add(vmdataGraph);
+    multiGraph1.Add(vmlckGraph);multiGraph1.Add(vmexeGraph);
+    multiGraph1.Add(vmstkGraph);#multiGraph1.Add(vmlibGraph);
+    multiGraph1.Add(inuseGraph);
+    multiGraph1.Add(sbrkGraph);multiGraph1.Add(mmapGraph);
+    multiGraph1.Add(holeGraph);multiGraph1.Add(freeGraph);
+
+
+    
+    #multiGraph1.SetTitle("PROCESS VM and Malloc MEMORY USAGE"); 
+    title.DrawPaveLabel(x1,y1,x2,y2,"PROCESS VM and Malloc MEMORY USAGE","brNDC");
+
+    multiGraph1.Draw("ALg")
+    hist = multiGraph1.GetHistogram(); hist.SetXTitle("Event Number"); hist.SetYTitle("Memory, kb");
+    legend1 = TLegend(0.84,0.20,0.99,0.90);
+    legend1.AddEntry(mapsGraph,  "Maps",            "l");
+    legend1.AddEntry(vmsizeGraph,"VmSize",          "l");
+    legend1.AddEntry(vmrssGraph, "VmRSS",           "l");
+    legend1.AddEntry(vmdataGraph,"VmData",          "l");
+
+    legend1.AddEntry(sbrkGraph,  "MallocSbrk",      "l");
+    legend1.AddEntry(inuseGraph, "MallocInuse",     "l");    
+    #legend1.AddEntry(vmlibGraph, "VmLib",          "l");
+    legend1.AddEntry(mmapGraph,  "MallocMmap",      "l");    
+    legend1.AddEntry(freeGraph,  "MallocFree",      "l");
+    legend1.AddEntry(holeGraph,  "Freed-Holes",     "l");     
+    legend1.AddEntry(vmstkGraph, "VmStk",           "l");
+    legend1.AddEntry(vmexeGraph, "VmExe",           "l");
+    legend1.AddEntry(vmlckGraph, "VmLck",           "l");
+    legend1.Draw();
+
+    #multiGraph1.Draw("ALg")    
+    #title.DrawPaveLabel(x1,y1,x2,y2,"Process Memory Usage Charts","brNDC");
+    
+    
+#Drawing upper-left corner Pad1 of the report
+    pad2.cd();
+    pad2.SetGridx(); pad2.SetGridy();
+
+    infoTree.Draw("total_hole_memory:scan_number", "", "goff");
+    holeGraph=TGraph(infoTree.GetSelectedRows(), infoTree.GetV2(), infoTree.GetV1())    
+    holeGraph.SetLineColor(9); holeGraph.SetLineWidth(1); holeGraph.SetFillStyle(3004); holeGraph.SetFillColor(5);
+    holeGraph.SetName("total_hole_memory"); 
+
+    mallocTree.Draw("malloc_free:scan_number", "", "goff");
+    freeGraph=TGraph(mallocTree.GetSelectedRows(), mallocTree.GetV2(), mallocTree.GetV1())    
+    freeGraph.SetLineColor(11); freeGraph.SetLineWidth(1); freeGraph.SetFillStyle(3004); freeGraph.SetFillColor(5);
+    freeGraph.SetName("malloc_free");
+    
+    pad2.cd();
+    multiGraph2.Add(holeGraph);
+    multiGraph2.Add(freeGraph);
+    #multiGraph2.Add(sbrkGraph);
+    #multiGraph2.Add(mmapGraph);
+    
+    #multiGraph2.SetTitle("Free and Marked Holes Memory Graph"); 
+    title.DrawPaveLabel(x1,y1,x2,y2,"Malloc Free and Marked Holes Memory","brNDC");
+    
+    multiGraph2.Draw("ALg")    
+    hist = multiGraph2.GetHistogram(); hist.SetXTitle("Event Number"); hist.SetYTitle("Memory, kb");
+    
+    legend2 = TLegend(0.9,0.30,0.99,0.90);
+    legend2.AddEntry(freeGraph,  "Free",   "l");
+    legend2.AddEntry(holeGraph,  "Holes",  "l");
+    #legend2.AddEntry(inuseGraph, "Inuse",  "l");
+    #legend2.AddEntry(mmapGraph,  "Mmap",  "l");
+    #legend2.AddEntry(sbrkGraph,  "Sbrk",  "l");
+
+    legend2.Draw()
+    #multiGraph2.Draw("ALg")    
+    #title.DrawPaveLabel(x1,y1,x2,y2,"Malloc Memory Usage and Deallocation Charts","brNDC");  
+  
+  #PAD3
+    pad3.cd()
+    pad3.SetLogz()
+    memHist1.Draw("lego2");
+    #title.DrawPaveLabel(x1,y1,x2,y2,"TH2I-LEGO2","brNDC");
+
+    mem_canvas.SetBorderSize(1);
+    #mem_canvas.Modified()
+    mem_canvas.Update()
+    mem_canvas.Print(".pdf")
+    mem_canvas.Print(".C")
\ No newline at end of file
diff --git a/Control/HeapMon/python/MemoryScanner.py b/Control/HeapMon/python/MemoryScanner.py
new file mode 100644
index 0000000000000000000000000000000000000000..b565c1a40e049b0c88a488fd693c8529c27ee217
--- /dev/null
+++ b/Control/HeapMon/python/MemoryScanner.py
@@ -0,0 +1,72 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+import os, sys;
+
+memscan_output = 'heapmon.holes.root'
+freescan_output = 'heapmon.freed.root'
+newscan_output = 'heapmon.newed.root'
+
+pid = os.getpid();
+free_marker = 0xCD; 
+new_marker = 0xBC;
+scan_number = 0;
+scan_flag = 1;
+free_scan_number = 0;
+new_scan_number = 0;
+
+memmarker = 'HeapMon.MemoryMarker' in sys.modules and \
+sys.modules[ 'HeapMon.MemoryMarker' ] or None
+
+#meminfo_file_name = 'mem'
+#print('    RunScanner is loaded: file name for memscan=', memscan_output)
+
+def nmemscan(file_name, scan_flag, n, id, mrkr = 0xCD):
+    global pid;
+    
+    try:
+        os.kill(id, 0)
+    except OSError, err:
+        print("pid ", id , " doesn't exist, so pid stays os.getpid()=", pid)
+        id = pid;
+    
+    print(' output_file ', file_name)
+    print ' scan_flag = ', scan_flag
+    print ' scan_number = ', n
+    
+    print('MemoryScanner.exe %d %d %d %s %d %s' %(id, scan_flag, n, file_name,  mrkr) );
+    os.system( 'MemoryScanner.exe %d %d %d %s %d %s' %(id, scan_flag, n, file_name,  mrkr)  );
+    
+def imemscan():
+    global pid, free_marker, scan_number, scan_flag, memscan_output  
+    print('MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, scan_number, memscan_output,  free_marker) );
+    os.system( 'MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, scan_number, memscan_output,  free_marker)  );
+    scan_number+=1
+    
+def memscan(file_name, scan_f, scan_n, marker):
+    global pid 
+    print('MemoryScanner.exe %d %d %d %s %d' %(pid, scan_f, scan_n, file_name,  marker) );
+    os.system( 'MemoryScanner.exe %d %d %d %s %d' %(pid, scan_f, scan_n, file_name,  marker)  );
+    
+def freescan(scan_flag):
+    global free_scan_number, free_marker
+    global freescan_output
+    print ('MemoryScanner.freescan(', scan_flag, ')')
+    print ' scan_flag = ', scan_flag
+    print ' scan_number = ', free_scan_number
+    #print ' RunScanner.memstat()'
+    print('MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, free_scan_number, freescan_output,  free_marker) );
+    os.system( 'MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, free_scan_number, freescan_output,  free_marker)  );
+
+    free_scan_number+=1
+
+def newscan(scan_flag):
+    global new_scan_number, new_marker
+    global newscan_output
+    print ('MemoryScanner.newscan(', scan_flag, ')')
+    print ' scan_flag = ', scan_flag
+    print ' scan_number = ', new_scan_number
+    #print ' RunScanner.memstat()'
+    print('MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, new_scan_number, newscan_output,  new_marker) );
+    os.system( 'MemoryScanner.exe %d %d %d %s %d' %(pid, scan_flag, new_scan_number, newscan_output,  new_marker)  );
+    new_scan_number+=1
+
diff --git a/Control/HeapMon/python/__init__.py b/Control/HeapMon/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a63ba62d7570caa7d1b86745aa4f5486b839063d
--- /dev/null
+++ b/Control/HeapMon/python/__init__.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# File: HeapMon/__init__.py
+# Author: Mous Tatarkhanov (MMTatarkhanov@lbl.gov) 
+
+__version__ = '0.0.1'
+__author__ = 'Mous Tatarkhanov (tmmous@berkeley.edu)'
+
+def setup():
+   import atexit, os
+   __path__.append( os.path.join( __path__[0], os.environ[ 'CMTCONFIG' ] ) )
+
+   from HeapMon import MemoryMarker
+   MemoryMarker.configure( MemoryMarker.IS_RUNNING )
+
+   atexit.register( MemoryMarker.atexit )
+
+setup()
+del setup
diff --git a/Control/HeapMon/share/heapmon_jobo.py b/Control/HeapMon/share/heapmon_jobo.py
new file mode 100755
index 0000000000000000000000000000000000000000..2f9081076d8a87523c26adca24a341ca891003e8
--- /dev/null
+++ b/Control/HeapMon/share/heapmon_jobo.py
@@ -0,0 +1,28 @@
+OutputLevel=INFO
+doCBNT=False
+EvtMax = 5
+
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+assert( job == AlgSequence() )     # this is a singleton
+
+from HeapMon.EventNotifier import EventExecutionNotifier
+een =EventExecutionNotifier('EventNotifier')
+een.start_scan = 1 
+een.stop_scan  = 4
+
+job.insert(0,een) 
+
+#DetDescrVersion="ATLAS-GEO-02-01-00"
+#PoolRDOInput = [ "RDO.pool.root" ]
+
+# DetFlags modifications are best set here (uncomment RecExCommon_flags first)
+#include ("RecExCond/RecExCommon_flags.py")
+# switch off ID, calo, or muons
+#DetFlags.ID_setOff()
+#DetFlags.Calo_setOff()
+#DetFlags.Muon_setOff()
+print job
+
+include ("jobOptions.py")
+#######################################################
diff --git a/Control/HeapMon/src/MemoryMarker.c b/Control/HeapMon/src/MemoryMarker.c
new file mode 100644
index 0000000000000000000000000000000000000000..50e0515723ab394492227cf9e74c0eb540e62fa8
--- /dev/null
+++ b/Control/HeapMon/src/MemoryMarker.c
@@ -0,0 +1,877 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//#ifndef HEAPMON_HEAPMON_H
+//#define HEAPMON_HEAPMON_H
+#if defined(__linux__)
+
+#define _GNU_SOURCE 1
+
+#include <stdio.h>
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+
+#include "Python.h"
+
+#include <execinfo.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <gperftools/malloc_hook_c.h>
+
+//#include <google/malloc_extension_c.h>
+void MallocExtension_GetStats(char*, int);
+size_t MallocExtension_GetAllocatedSize(void*);
+int mm_check(int);
+int mm_clearCheckPoint(int);
+int mm_depth(int);
+int mm_setCheckPoint(void);
+void get_trace(long);
+void get_key_list(void);
+void trace(const char*);
+
+
+// copied from malloc.c
+/* -------------- Early definitions for debugging hooks ---------------- */
+/* Define and initialize the hook variables.  These weak definitions must
+   appear before any use of the variables in a function (arena.c uses one).  */
+#ifndef weak_variable
+#ifndef _LIBC
+#define weak_variable /**/
+#else
+/* In GNU libc we want the hook variables to be weak definitions to
+   avoid a problem with Emacs.  */
+#define weak_variable weak_function
+#endif
+#endif
+
+
+/*- data ------------------------------------------------------------------- */
+
+/* holder to locate this shared library */
+void mm_dummy() {}
+
+// defined below
+static  void tc_MallocHook(const void* ptr, size_t size);
+static  void tc_FreeHook(const void* ptr);
+
+static MallocHook_NewHook old_tcMalloc_hook_ = NULL ;
+static MallocHook_DeleteHook old_tcFree_hook_ = NULL;
+
+/* forward declarations */
+static void mm_Hooks_uninstall();
+static void *mm_MallocHook( size_t size, const void *caller );
+static void *mm_ReallocHook( void *ptr, size_t size, const void *caller );
+static void mm_FreeHook( void *ptr, const void *caller );
+
+/* holders for original hooks */
+static void *(*m_OldMallocHook)  ( size_t size, const void *caller );
+static void *(*m_OldReallocHook) ( void *ptr, size_t size, const void *caller );
+static void (*m_OldFreeHook)     ( void *ptr, const void *caller );
+
+/* available flags */
+#define IS_RUNNING          1
+#define LEAK_CHECK          2
+#define PROFILE             4
+#define HIDEMEMADDR         8
+#define QUICK              16
+#define STL_CHECKS         32
+#define FILTER_STL         64
+#define IS_MARKING		  128
+
+#define SIZE_MARK 		'\xFB'
+
+static unsigned char FREE_MARKER	= 	'\xCD';
+static unsigned char NEW_MARKER 	=	'\xBC';
+//static short int MAX_EVENT_NUMBER 	=	10;
+
+static unsigned char USETCMALLOC = 1;
+
+/* module-level configuration flags */
+static long gFlags = 0;
+static size_t  LOWER_THREE_BITS = (0x01|0x02|0x04);
+static long event_counter = 0;
+
+static unsigned long long total_freed = 0;
+static unsigned long long total_allocated = 0;
+static unsigned long long number_freed = 0;
+static unsigned long long number_allocated = 0;
+static unsigned long long number_zero_allocated = 0;
+static unsigned long long number_zeroptr_freed = 0;
+static struct mallinfo mem_struct;
+
+/* handle to output stream used */
+static FILE *file_output = 0;
+
+void * old_ptr;
+static char buffer[512];
+
+
+
+/* _________________________________________________________________________ */
+static void mm_report( void ) {
+	printf("	MemoryMarker->mm_report(): gFlags = %u\n", gFlags);
+}
+
+
+/* _________________________________________________________________________ */
+static void ignore( const char *name ) {
+	gFlags = gFlags & ~IS_MARKING;
+	printf("	MemoryMarker->ignore(): IS_MARKING flag dropped. gFlags = %u\n", gFlags);
+}
+
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_save() {
+	switch(USETCMALLOC){
+	case 0:
+		/* store old glibc hooks in buffer for reset later; prevent storing ourselves in
+		   case of a double-call by the user (e.g. from python) */
+		//printf("	MemoryMarker->mm_Hooks_save ptmalloc gFlags = %u\n", gFlags);
+
+		   /*if ( __malloc_hook != mm_MallocHook )
+		      m_OldMallocHook  = __malloc_hook;
+		   if ( __realloc_hook != mm_ReallocHook )
+		      m_OldReallocHook = __realloc_hook; */
+		   if ( __free_hook != mm_FreeHook )
+		      m_OldFreeHook    = __free_hook;
+		break;
+	case 1:
+		printf("	MemoryMarker->mm_Hooks_save tcmalloc gFlags = %u\n", gFlags);
+		break;
+	default:
+		printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+	}
+}
+
+/* _________________________________________________________________________ */
+static long configure( long flags ) {
+	gFlags |= IS_RUNNING;
+	gFlags |= flags;
+
+	printf("	MemoryMarker->configure(): IS_RUNNING flag raised. gFlags = %u\n", gFlags);
+
+	//setup();
+	switch(USETCMALLOC){
+	case 0:
+		mm_Hooks_save();
+		break;
+	case 1:
+		printf("	MemoryMarker->configure() tcmalloc gFlags = %u\n", gFlags);
+		break;
+	default:
+		printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+	}
+	return gFlags;
+}
+
+static void set_marker(char m) {
+	FREE_MARKER = m;
+}
+
+static void get_test(long lkey) {
+
+	struct mallinfo mem_struct;
+
+	switch(USETCMALLOC){
+	case 0:
+			printf("MemoryMarker->get_test()->Malloc Stats:\n");
+			printf("--------------------------MALLOC INFO --------------\n");
+			malloc_stats();
+
+			mem_struct = mallinfo();
+			printf("	sbrk-Allocated Memory( ARENA) size: %lu\n", mem_struct.arena);
+			printf(" 	MMAP-Allocated Memory: %lu\n", mem_struct.hblkhd);
+			printf(" 	Number of chunks allocated by MMAP: %lu\n", mem_struct.hblks);
+			printf(" 	MALLOC-In Use: %lu\n", mem_struct.uordblks );
+			printf(" 	MALLOC-Free: %lu\n", mem_struct.fordblks);
+			printf(" 	Number of chunks from OS not in use by MALLOC: %lu\n", mem_struct.ordblks);
+			printf("    Top-releasable chunk keepcost: %lu\n", mem_struct.keepcost);
+
+			printf("-----------------------------------------------------\n\n");
+
+			/*
+			printf("   gnu_libc_version= %s\n",gnu_get_libc_version());
+			printf("------------------Sizes and Ranges of Integer Types-------------------\n");
+			printf(" NUMBER OF BITS in types: \n");
+
+			printf("   CHAR_BIT=%u, SHRT_BIT=%u, INT_BIT=%u, LONG_BIT=%u, LONG_LONG_BIT=%u\n",
+			             CHAR_BIT, sizeof(signed short int)*CHAR_BIT,sizeof(signed int)*CHAR_BIT,
+			         sizeof(signed long int)*CHAR_BIT, sizeof(signed long long int)*CHAR_BIT);
+			printf(" \n");
+			printf("   sizeof(size_t)=%u\t\tsizeof(ptrdiff_t)=%u\n",sizeof(size_t), sizeof(ptrdiff_t));
+			printf(" TYPE RANGES:\n");
+			printf("   CHAR_MIN=%d\t\tCHAR_MAX=%d\t\tUCHAR_MAX=%u\n", CHAR_MIN, CHAR_MAX, UCHAR_MAX);
+			printf("   SHRT_MIN=%d\t\tSHRT_MAX=%d\t\tUINT_MAX=%u\n", SHRT_MIN, SHRT_MAX, USHRT_MAX);
+			printf("   INT_MIN=%d\t\tINT_MAX=%d\t\tUINT_MAX=%u\n", INT_MIN, INT_MAX, UINT_MAX);
+			printf("   LONG_MIN=%e\t\tLONG_MAX=%e\tULONG_MAX=%e\n", LONG_MIN*1.0, LONG_MAX*1.0,ULONG_MAX*1.0 );
+			printf("   LONG_LONG_MIN=%e\tLONG_LONG_MAX=%e\tULONG_LONG_MAX=%e\n", LONG_LONG_MIN*1.0, LONG_LONG_MAX*1.0, ULONG_LONG_MAX*1.0);
+			printf("----------------------------------------------------------------------\n");
+			*/
+		break;
+	case 1:
+		mem_struct = mallinfo();
+		printf("	MemoryMarker->get_test tcmalloc gFlags = %u\n", gFlags);
+		printf("	sbrk-Allocated Memory( ARENA) size: %lu\n", mem_struct.arena);
+		//printf(" 	MMAP-Allocated Memory: %lu\n", mem_struct.hblkhd);
+		//printf(" 	Number of chunks allocated by MMAP: %lu\n", mem_struct.hblks);
+		printf(" 	MALLOC-In Use: %lu\n", mem_struct.uordblks );
+		printf(" 	MALLOC-Free: %lu\n", mem_struct.fordblks);
+		//printf(" 	Number of chunks from OS not in use by MALLOC: %lu\n", mem_struct.ordblks);
+		//printf("    Top-releasable chunk keepcost: %lu\n", mem_struct.keepcost);
+		break;
+	default:
+		printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+	}
+
+}
+
+static void store_malloc_info() {
+	//printf("MemoryMarker->store_malloc_info() store malloc data into file:\n");
+	malloc_stats();
+}
+
+static void show_malloc_info() {
+
+	switch(USETCMALLOC){
+	case 0:
+		printf("\n--------- GLIBC ptmalloc( --stdcmalloc) INFO --------\n");
+		malloc_stats();
+		mem_struct = mallinfo();
+		printf("  SBRK-allocated memory( ARENA) size: %lu bytes\n", mem_struct.arena);
+		printf("  MMAP-allocated memory: %lu bytes\n", mem_struct.hblkhd);
+		printf("  MMAP-allocated number of chunks: %lu\n", mem_struct.hblks);
+		printf("  MALLOC-In-use: %lu bytes \n", mem_struct.uordblks );
+		printf("  MALLOC-Free: %lu bytes\n", mem_struct.fordblks);
+		printf("  Number of chunks from OS not in use by MALLOC: %lu \n", mem_struct.ordblks);
+		printf("  TOP-releasable chunk keepcost: %lu bytes \n\n", mem_struct.keepcost);
+
+		printf("\n-------------- HEAPMON MEMORY MARKER SPECIFIC INFO -------\n");
+		printf(" Cumulative allocated memory size: %u bytes\n", total_allocated);
+		printf(" Cumulative deallocated memory: %u bytes \n", total_freed);
+		printf(" Number of allocations: %u bytes \n", number_allocated);
+		printf(" Number of deallocations: %u  \n", number_freed);
+		printf(" Number of zero allocations: %u\n", number_zero_allocated);
+		printf(" Number of zero ptr deallocations: %u\n", number_zeroptr_freed);
+		printf("-----------------------------------------------------------\n\n");
+		break;
+	case 1:
+
+		mem_struct = mallinfo();
+		printf("\n-------------- TCMALLOC INFO -------------------------\n");
+		printf("	MemoryMarker->get_test tcmalloc gFlags = %u\n", gFlags);
+		printf("	SBRK-allocated Memory( ARENA) size: %lu bytes\n", mem_struct.arena);
+		//printf(" 	MMAP-Allocated Memory: %lu\n", mem_struct.hblkhd);
+		//printf(" 	Number of chunks allocated by MMAP: %lu\n", mem_struct.hblks);
+		printf(" 	MALLOC-In Use: %lu bytes \n", mem_struct.uordblks );
+		printf(" 	MALLOC-Free: %lu bytes \n", mem_struct.fordblks);
+		//printf(" 	Number of chunks from OS not in use by MALLOC: %lu\n", mem_struct.ordblks);
+		//printf("    Top-releasable chunk keepcost: %lu\n", mem_struct.keepcost);
+		printf("-----------------------------------------------------------\n\n");
+
+
+		MallocExtension_GetStats(buffer, 512);
+		printf("  MemoryMarker->get_malloc_info() tcmalloc gFlags = %u\n", gFlags);
+		printf("  tcmalloc stats: %s", buffer);
+
+		printf("\n-------------- HEAPMON MEMORY MARKER SPECIFIC INFO -------\n");
+		printf("	Cumulative allocated memory size: %u\n", total_allocated);
+		printf(" 	Cumulative deallocated memory: %u\n", total_freed);
+		printf(" 	Number of allocations: %u\n", number_allocated);
+		printf(" 	Number of deallocations: %u\n", number_freed);
+		printf(" 	Number of zero allocations: %u\n", number_zero_allocated);
+		printf(" 	Number of zero ptr deallocations: %u\n", number_zeroptr_freed);
+		printf("-----------------------------------------------------------\n\n");
+
+
+		break;
+	default:
+		printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+		printf("\n-------------- HEAPMON MEMORY MARKER SPECIFIC INFO -------\n");
+		printf("	Cumulative allocated memory size: %u\n", total_allocated);
+		printf(" 	Cumulative deallocated memory: %u\n", total_freed);
+		printf(" 	Number of allocations: %u\n", number_allocated);
+		printf(" 	Number of deallocations: %u\n", number_freed);
+		printf(" 	Number of zero allocations: %u\n", number_zero_allocated);
+		printf(" 	Number of zero ptr deallocations: %u\n", number_zeroptr_freed);
+		printf("-----------------------------------------------------------\n\n");
+
+	}
+}
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_install() {
+
+   if ( gFlags & IS_RUNNING ) {
+		switch(USETCMALLOC){
+		case 0:
+			//printf("	MemoryMarker->mm_Hooks_install(): mm_Hooks installed. gFlags = %u\n", gFlags);
+			__free_hook    = mm_FreeHook;
+			/*__malloc_hook  = mm_MallocHook;
+			__realloc_hook = mm_ReallocHook;*/
+			break;
+		case 1:
+			printf("	MemoryMarker->mm_Hooks_install() tcmalloc gFlags = %u\n", gFlags);
+			break;
+		default:
+			printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+		}
+
+   } else{
+	   printf("	MemoryMarker->mm_Hooks_install(): mm_Hooks failed to install. IS_RUNNING not set, gFlags = %u\n", gFlags);
+   }
+   return ;
+}
+
+static void tc_Hooks_install() {
+   if ( gFlags & IS_RUNNING ) {
+	   printf(" MemoryMarker->tc_Hooks_install(): do nothing! gFlags = %u\n", gFlags);
+
+   } else{
+	   printf("	MemoryMarker->tc_Hooks_install(): 'IS_RUNNING' not set, gFlags = %u  do nothing!\n", gFlags);
+   }
+   return ;
+}
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_uninstall() {
+	switch(USETCMALLOC){
+	case 0:
+		//printf("	MemoryMarker->mm_Hooks_uninstall(), gFlags = %u\n", gFlags);
+		__free_hook    = 	m_OldFreeHook;
+		/*__malloc_hook  = 	m_OldMallocHook;
+		__realloc_hook = 	m_OldReallocHook;*/
+		break;
+	case 1:
+		printf("	MemoryMarker->mm_Hooks_uninstall() tcmalloc gFlags = %u\n", gFlags);
+		break;
+	default:
+		printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+	}
+}
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_start() {
+	if ( (gFlags & IS_RUNNING) ){
+		switch(USETCMALLOC){
+		case 0:
+			printf("	MemoryMarker->mm_Hooks_start().");
+			mm_Hooks_save();
+			mm_Hooks_install();//__free_hook    = mm_FreeHook;
+			break;
+		case 1:
+			if (!(gFlags & IS_MARKING)){
+				printf("	MemoryMarker->tc_Hooks_start().");
+				old_tcFree_hook_ = MallocHook_SetDeleteHook(tc_FreeHook);
+				//old_tcMalloc_hook_ = MallocHook_SetNewHook(tc_MallocHook);
+				if (old_tcFree_hook_)
+					printf("   MemoryMarker-> HeapMon Delete hook set and old_tcFree_hook successfully saved");
+				//if (old_tcMalloc_hook_ != NULL)
+					//printf("   MemoryMarker-> HeapMon New hook set and old_tcMalloc_hook successfully saved");
+			} else{
+				printf("   MemoryMarker-> HeapMon hook has been already set");
+			}
+			break;
+		default:
+			printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+		}
+	   gFlags |= IS_MARKING;
+	   printf("	IS_MARKING flag raised, gFlags = %u!\n", gFlags);
+	} else {
+	   printf("	MemoryMarker->mm_Hooks_start(): Attempt failed: IS_RUNNING flag is not set, gFlags = %u!\n", gFlags);
+	}
+}
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_stop() {
+	if (gFlags & IS_MARKING){
+		switch(USETCMALLOC){
+		case 0:
+			printf("	MemoryMarker->mm_Hooks_stop(): old hooks restored and IS_MARKING dropped");
+			//__free_hook   = m_OldFreeHook;
+			mm_Hooks_uninstall();
+			break;
+		case 1:
+			printf("	MemoryMarker->mm_Hooks_stop(): old tc_hooks restored\n");
+			if (MallocHook_SetDeleteHook(old_tcFree_hook_)!=NULL)
+				printf("	old tcmalloc Delete hook restored!\n");
+			//if (MallocHook_SetNewHook(old_tcMalloc_hook_)!=NULL)
+				//printf("	old tcmalloc New hook restored!\n");
+			break;
+		default:
+			printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+		}
+
+		gFlags &= gFlags ^ IS_MARKING;
+		printf(", gFlags = %u\n", gFlags);
+	} else{
+		printf("	MemoryMarker->mm_Hooks_stop(): Attempt failed (IS_MARKING  not raised) gFlags = %u. \n", gFlags);
+	}
+}
+
+/* _________________________________________________________________________ */
+static void mm_Hooks_atexit() {
+   printf("	MemoryMarker->mm_Hooks_atexit(): mm_Hooks _uninstall(). gFlags = %u\n", gFlags);
+
+   switch(USETCMALLOC){
+   case 0:
+	   /* reset (system/NULL) hook to prevent tracking */
+	   mm_Hooks_uninstall();
+	   break;
+   case 1:
+	   printf("	MemoryMarker->mm_Hooks_atexit(): tc_Hooks _uninstall()\n");
+	   if (old_tcFree_hook_!=NULL){
+		   if (MallocHook_SetDeleteHook(old_tcFree_hook_)!=NULL)
+			   printf("			old tcmalloc Delete hook restored successfull!\n");
+		   //if (MallocHook_SetNewHook(old_tcMalloc_hook_)!=NULL)
+			   //printf("			old tcmalloc New hook restored successfull!\n");
+	   }
+	   break;
+   default:
+	   printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+   }
+
+   gFlags &= gFlags ^ IS_MARKING;
+   gFlags &= gFlags ^ IS_RUNNING;
+   printf("	MemoryMarker->mm_Hooks_atexit(): IS_MARKING and IS_RUNNING flags dropped  gFlags = %u\n", gFlags);
+}
+
+
+/* _________________________________________________________________________ */
+static void *mm_MallocHook( size_t size, const void *unused ) {
+   void *result;
+
+/* reset (system/NULL) hook to prevent recursion */
+   mm_Hooks_uninstall();
+
+/* let malloc do its thing */
+   result = malloc( size );
+
+   if (size > 8 && result!=0)
+	   memset(result, NEW_MARKER, size - 8);
+
+/* store current hooks */
+   mm_Hooks_save();
+
+/* reset tracker hook */
+   mm_Hooks_install();
+
+   return result;
+}
+
+/* _________________________________________________________________________ */
+static void *mm_ReallocHook( void *ptr, size_t size, const void *unused ) {
+   void *result;
+
+/* reset (system/NULL) hook to prevent recursion */
+   mm_Hooks_uninstall();
+
+/* let realloc do its thing */
+   result = realloc( ptr, size );
+
+   //memset(result, NEW_MARKER, size);
+
+/* store current hooks */
+   mm_Hooks_save();
+
+/* reset tracker hook */
+   mm_Hooks_install();
+
+   return result;
+}
+
+void *secureMemset(void *v, int c,size_t n) {
+	volatile char *p = v;
+	while (n--)
+		*p++ = c;
+
+	return v;
+}
+
+static void tc_MallocHook(const void* ptr, size_t size){
+	if (size == 0){
+		//printf("  alloc_size=0  ");
+		number_zero_allocated+=1;
+	} else {
+
+		total_allocated +=size;
+		number_allocated +=1;
+
+		/*if (size > 1)
+			memset(ptr, FREE_MARKER, object_size - 1);*/
+
+		if (size > 50000)
+			printf("malloc=%d", size);
+	}
+
+}
+
+static void tc_FreeHook(const void *ptrv) {
+	size_t* ptr = (size_t *) ptrv;
+	if( ptr!=NULL && ptr!=0){
+		//printf("ptr=%x", ptr);
+		size_t object_size = 0;
+		object_size = MallocExtension_GetAllocatedSize(ptr);
+
+		if (object_size < 1)
+			return;
+		total_freed +=object_size;
+		number_freed +=1;
+		if (object_size < 2){
+			printf("free=1");
+			memset(ptr , FREE_MARKER, 		object_size - 2 );
+		} else if (object_size < 10){
+			//printf("`");
+			memset(ptr, FREE_MARKER, 		object_size - 2 );
+		} else if (object_size < 250){ //14 size_t memory slots
+			//printf("!");
+			memset(ptr , FREE_MARKER, 	object_size - 8 );
+		} else if (object_size < 350){
+			//printf("#");
+			memset(ptr + 50, FREE_MARKER, 16);
+			memset(ptr + 52, SIZE_MARK, 12);
+
+			char* cp_ptr = (char*)(ptr + 53); //pointer to the memory where object_size is recorded byte-by-byte
+			char* cp_object_size = (char *)(&object_size); // get the value stored at pI
+			int x = 0;
+			for( x = 0; x < sizeof(object_size); x++){
+				char temp = *cp_object_size; // get the value of first byte of object_size
+				memset(cp_ptr + x, temp, 1);
+				cp_object_size++; // Point to next byte of object_size
+			}
+		} else {
+
+			//printf("$");
+			//memset(ptr, FREE_MARKER, object_size - 8);
+			memset(ptr + 50, FREE_MARKER, 16);
+			memset(ptr + 52, SIZE_MARK, 12);
+
+			char* cp_ptr = (char*)(ptr + 53); //pointer to the memory where object_size is recorded byte-by-byte
+			char* cp_object_size = (char *)(&object_size); // get the value stored at pI
+			int x = 0;
+			for( x = 0; x < sizeof(object_size); x++){
+				char temp = *cp_object_size; // get the value of the x-th byte of object_size
+				memset(cp_ptr + x, temp, 1);
+				cp_object_size++; // Point to next byte of object_size
+			}
+			/*if(object_size >= 350 && object_size <=450){
+				int y=0;
+				for(y = 0; y < 5; y++){
+					//printf(" ptr=%x, value=%u(%x) ",ptr+y, 	*((long *) (ptr+y)),  *((long *) (ptr+y)));
+				}
+			}*/
+  		}
+	} else{
+		//printf("ptr=NULL/0");
+		number_zeroptr_freed += 1;
+	}
+}
+
+/* _________________________________________________________________________ */
+static void mm_FreeHook( void *ptr, const void *caller ) {
+/* reset (system/NULL) hook to prevent recursion */
+   mm_Hooks_uninstall();
+
+     size_t* chunk_ptr ;
+     size_t* next_chunk_ptr;
+     unsigned long   object_size = 0;
+     unsigned long   chunk_size = 0;
+
+     if(ptr){
+		chunk_ptr = (size_t*)(ptr-1*sizeof(size_t));
+		chunk_size = (*chunk_ptr) & ~LOWER_THREE_BITS;
+		//object_size = ((*chunk_ptr) & ~LOWER_THREE_BITS) - 2*sizeof(size_t);
+		object_size = chunk_size - 2*sizeof(size_t);
+		memset(ptr, FREE_MARKER, object_size);
+     }
+     free( ptr );
+
+/* store current hooks */
+   mm_Hooks_save();
+
+/* reset tracker hook */
+   mm_Hooks_install();
+
+}
+
+
+/*========================================================================== */
+/* startup and shutdown */
+/*========================================================================== */
+static void setup() __attribute__ ((constructor));
+static void report() __attribute__ ((destructor));
+
+/* _________________________________________________________________________ */
+static void setup() {
+   printf("MemoryMarker->setup()->mm_Hooks_save()\n");
+   //find out if tcmalloc was loaded
+   USETCMALLOC = strcmp(getenv("USETCMALLOC"), "true") ? 0 : 1;
+   printf("  USETCMALLOC=%d", USETCMALLOC);
+   if (USETCMALLOC) {
+	   printf("  tcmalloc is loaded \n");
+   } else {
+	   printf("  glibc malloc is working \n");
+	   mm_Hooks_save();
+   }
+
+}
+
+/* _________________________________________________________________________ */
+static void report() {
+   static int finalized = 0;
+	printf("MemoryMarker->report()->mm_Hooks_uninstall()\n");
+   //unsigned int iname;
+    //  finalized = 1;
+
+   /* reset (system/NULL) as we're done now */
+      mm_Hooks_uninstall();
+
+}
+
+
+/*========================================================================== */
+/* python interface module */
+/*========================================================================== */
+#define CPPTOPYTHON( fname )                                                  \
+static PyObject* hep_##fname( PyObject* unused, PyObject* args ) {            \
+   if ( ! PyArg_ParseTuple( args, (char*)":"#fname ) )                        \
+      return 0;                                                               \
+                                                                              \
+   mm_Hooks_##fname();                                                       \
+                                                                              \
+   Py_INCREF( Py_None );                                                      \
+   return Py_None;                                                            \
+}
+CPPTOPYTHON( install )
+CPPTOPYTHON( start )
+CPPTOPYTHON( stop )
+CPPTOPYTHON( uninstall )
+CPPTOPYTHON( atexit )
+
+/* _________________________________________________________________________ */
+#define CPPTOPYTHONWITHSTRING( fname )                                        \
+static PyObject* hep_##fname( PyObject* unused, PyObject* args ) {            \
+   const char *name;                                                          \
+   PyStringObject* pyname = 0;                                                \
+   if ( ! PyArg_ParseTuple( args, (char*)"S:"#fname, &pyname ) )              \
+      return 0;                                                               \
+                                                                              \
+   name = PyString_AS_STRING( pyname );                                       \
+   fname( name );                                                             \
+                                                                              \
+   Py_INCREF( Py_None );                                                      \
+   return Py_None;                                                            \
+}
+CPPTOPYTHONWITHSTRING( trace )
+CPPTOPYTHONWITHSTRING( ignore )
+
+/* _________________________________________________________________________ */
+#define CPPTOPYTHONWITHINT( fname )                                           \
+static PyObject* hep_##fname( PyObject* unused, PyObject* args ) {            \
+  int i,res;                                                                  \
+   if ( ! PyArg_ParseTuple( args, "i", &i ) )                                 \
+      return 0;                                                               \
+                                                                              \
+   res = mm_##fname( i );                                                    \
+   return Py_BuildValue( "i", res );                                          \
+}
+CPPTOPYTHONWITHINT( check )
+CPPTOPYTHONWITHINT( clearCheckPoint )
+CPPTOPYTHONWITHINT( depth )
+
+static PyObject* hep_set_marker(PyObject* unused, PyObject* args ){
+	char c;
+	if (! PyArg_ParseTuple(args, "c", &c) )
+		return 0;
+	set_marker(c);
+
+	Py_INCREF( Py_None );                                                      \
+	return Py_None;
+}
+
+static PyObject* hep_get_marker(PyObject* unused, PyObject* args ){
+	PyObject* py_return = 0;
+	py_return = Py_BuildValue("c", FREE_MARKER);
+	return py_return;
+}
+
+/* _________________________________________________________________________ */
+static PyObject* hep_setCheckPoint( PyObject* unused, PyObject* args ) {
+  int res = mm_setCheckPoint();
+  return Py_BuildValue( "i", res );
+}
+
+/* _________________________________________________________________________ */
+static PyObject* hep_configure( PyObject* unused, PyObject* args ) {
+   long flags = 0;
+   if ( ! PyArg_ParseTuple( args, (char*)"|l:configure", &flags ) )
+      return 0;
+
+   flags = configure( flags );
+
+   return PyLong_FromLong( flags );
+}
+
+static PyObject* hep_get_trace( PyObject* unused, PyObject* args ) {
+   long key = 0;
+   if ( ! PyArg_ParseTuple( args, (char*)"|l:get_trace", &key ) )
+      return 0;
+
+   get_trace( key );
+
+   Py_INCREF( Py_None );
+   return Py_None;
+}
+
+static PyObject* hep_get_test( PyObject* unused, PyObject* args ) {
+   long key = 0;
+   if ( ! PyArg_ParseTuple( args, (char*)"|l:get_test", &key ) )
+      return 0;
+
+   get_test( key );
+
+   Py_INCREF( Py_None );
+   return Py_None;
+}
+
+static PyObject* hep_store_malloc_info( PyObject* unused, PyObject* args ) {
+   unsigned int number = 0;
+   const char * name;
+   PyStringObject* pyname = 0;
+
+   if ( ! PyArg_ParseTuple( args, (char*)"is:store_malloc_info", &number, &pyname) )
+      return 0;
+
+   name = PyString_AS_STRING( pyname );
+   //store_malloc_info(number, name);
+
+   Py_INCREF( Py_None );
+   return Py_None;
+}
+
+static PyObject* hep_get_malloc_info( PyObject* unused, PyObject* args ) {
+   PyStringObject* pyname = 0;
+   PyObject* py_return = 0;
+   struct mallinfo mem_struct;
+   mem_struct = mallinfo();
+
+   switch(USETCMALLOC){
+   case 0: //ptmalloc(glibc)
+	   /* reset (system/NULL) hook to prevent tracking */
+		/*printf("	sbrk-Allocated Memory( ARENA) size: %lu\n", mem_struct.arena);
+		printf(" 	MMAP-Allocated Memory: %lu\n", mem_struct.hblkhd);
+		printf(" 	Number of chunks allocated by MMAP: %lu\n", mem_struct.hblks);
+		printf(" 	MALLOC-In Use: %lu\n", mem_struct.uordblks );
+		printf(" 	MALLOC-Free: %lu\n", mem_struct.fordblks);
+		printf(" 	Number of chunks from OS not in use by MALLOC: %lu\n", mem_struct.ordblks);
+		printf("    Top-releasable chunk keepcost: %lu\n", mem_struct.keepcost);*/
+
+	   py_return = Py_BuildValue("llll",
+			   mem_struct.arena/1024, 	//sbrk
+			   mem_struct.hblkhd/1024, 	//mmap
+			   mem_struct.uordblks/1024, //inuse
+			   mem_struct.fordblks/1024);//free
+	   break;
+   case 1: //tcmalloc
+	   py_return = Py_BuildValue("llll",
+			   mem_struct.arena/1024, 	//sbrk
+			   1, 	//for tcmalloc not defined
+			   mem_struct.uordblks/1024, //inuse
+			   mem_struct.fordblks/1024);//free
+	   //get_malloc_info();
+	   break;
+   default:
+	   printf(" Invalid USETCMALLOC key: %d", USETCMALLOC);
+	   show_malloc_info();
+   }
+
+   return py_return;
+}
+
+static PyObject* hep_show_info( PyObject* unused, PyObject* args ) {
+	   show_malloc_info( );
+	   Py_INCREF( Py_None );
+	   return Py_None;
+}
+
+static PyObject* hep_get_key_list( PyObject* unused, PyObject* args ) {
+   long key = 0;
+   if ( ! PyArg_ParseTuple( args, (char*)"|l:get_key_list", &key ) )
+      return 0;
+
+   get_key_list( );
+
+   Py_INCREF( Py_None );
+   return Py_None;
+}
+
+/* _________________________________________________________________________ */
+static PyObject* hep_outstream( PyObject* unused, PyObject* args ) {
+   PyObject* pyfile;
+   if ( ! PyArg_ParseTuple( args, "O!", &PyFile_Type, &pyfile ) )
+      return 0;
+
+   FILE* fp = PyFile_AsFile( pyfile );
+   if ( ! fp )
+      return 0;
+
+   int fd = dup( fileno( fp ) );
+
+   file_output = fdopen( fd, "w" );
+
+   Py_INCREF( Py_None );
+   return Py_None;
+}
+
+/* _________________________________________________________________________ */
+static PyMethodDef gMemoryMarkerMethods[] = {
+   { (char*)"install",   (PyCFunction)hep_install,   METH_VARARGS, (char*)"install/start marking" },
+   { (char*)"start",     (PyCFunction)hep_start,     METH_VARARGS, (char*)"start marking" },
+   { (char*)"stop",      (PyCFunction)hep_stop,      METH_VARARGS, (char*)"stop marking" },
+   { (char*)"uninstall", (PyCFunction)hep_uninstall, METH_VARARGS, (char*)"uninstall marking" },
+   { (char*)"atexit",    (PyCFunction)hep_atexit,    METH_VARARGS, (char*)"atexit handler" },
+   { (char*)"ignore",    (PyCFunction)hep_ignore,    METH_VARARGS, (char*)"ignore memory marking by dropping IS_MARKING flag" },
+   { (char*)"configure", (PyCFunction)hep_configure, METH_VARARGS, (char*)"prepare for memory marking by raising IS_MARKING flag" },
+   { (char*)"outstream", (PyCFunction)hep_outstream, METH_VARARGS, (char*)"set new outstream" },
+   { (char*)"get_test",  (PyCFunction)hep_get_test,  METH_VARARGS, (char*)"get test information" },
+   { (char*)"store_malloc_info", (PyCFunction)hep_store_malloc_info,  	METH_VARARGS, (char*)"store Malloc-info into ROOT file using C++ extern function - doesn't work for now" },
+   { (char*)"get_malloc_info", (PyCFunction)hep_get_malloc_info,  		METH_VARARGS, (char*)"get Malloc-info in the tuple" },
+   { (char*)"show_info", (PyCFunction)hep_show_info,  					METH_VARARGS, (char*)"show mempory usage info" },
+   { (char*)"set_marker",  (PyCFunction)hep_set_marker,  METH_VARARGS, (char*)"set marker_char to build marker" },
+   { (char*)"get_marker",  (PyCFunction)hep_get_marker,  METH_VARARGS, (char*)"get current marker_char" },
+   { NULL, NULL, 0, NULL }
+};
+
+
+/* _________________________________________________________________________ */
+void initMemoryMarker() {
+   PyObject *memmark;
+
+   memmark = Py_InitModule( (char*)"MemoryMarker", gMemoryMarkerMethods );
+
+/* configuration flags */
+   PyModule_AddObject( memmark, (char*)"LEAK_CHECK", PyLong_FromLong( LEAK_CHECK ) );
+   PyModule_AddObject( memmark, (char*)"PROFILE",    PyLong_FromLong( PROFILE ) );
+   PyModule_AddObject( memmark, (char*)"HIDEMEMADDR",PyLong_FromLong( HIDEMEMADDR ) );
+   PyModule_AddObject( memmark, (char*)"QUICK",      PyLong_FromLong( QUICK ) );
+   PyModule_AddObject( memmark, (char*)"STL_CHECKS", PyLong_FromLong( STL_CHECKS ) );
+   PyModule_AddObject( memmark, (char*)"FILTER_STL", PyLong_FromLong( FILTER_STL ) );
+   PyModule_AddObject( memmark, (char*)"IS_MARKING", PyLong_FromLong( IS_MARKING ) );
+   PyModule_AddObject( memmark, (char*)"IS_RUNNING", PyLong_FromLong( IS_RUNNING ) );
+}
+
+#endif
diff --git a/Control/HeapMon/src/MemoryScanner.cxx b/Control/HeapMon/src/MemoryScanner.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8e011ac5b52a6166e4678c5d96e1cf2d37c6048e
--- /dev/null
+++ b/Control/HeapMon/src/MemoryScanner.cxx
@@ -0,0 +1,490 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+MEMORY SCANNER
+*/
+
+// standard includes
+#include <iostream>
+using namespace std;
+
+// C includes
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+
+//system includes
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+// STL includes
+#include <map>
+#include <vector>
+#include <iostream>
+#include <iterator>
+
+// ROOT includes
+#include <TTree.h>
+#include <TFile.h>
+#include <TF1.h>
+#include <TH1.h>
+#include <TH2.h>
+#ifdef __APPLE__
+#define PTRACE_ATTACH PT_ATTACH
+#define PTRACE_DETACH PT_DETACH
+#endif
+
+int usage( char* name ){
+   cout << "usage: " << name <<" <pid> <scan_flag=0|1|2|3|4> <scan_number> <output_file_name> <marker-type(not-used-yet)>\n";
+   return 2;
+}
+
+
+int main( int argc, char *argv[] ){
+	typedef unsigned int ms_uint64;
+	typedef unsigned int ms_uint32;
+
+	int result = -1;
+	FILE *maps = 0;
+	FILE *statusf = 0;
+	int mem = 0;
+	pid_t pid = 0;
+
+	unsigned short int SCAN_FLAG = 0;
+	unsigned short int scan_number = 0;
+
+	char mapfile[128], memfile[128], statusfile[128];
+	char *buffer = NULL;
+
+	ms_uint32 marker 	= 	0xCDCDCDCD; // new_marker = 	0xBCBCBCBC;
+	ms_uint32 size_mark 	= 	0xFBFBFBFB;
+	ms_uint64  addr_start = 0, addr_end = 0;
+
+	siginfo_t *infop = NULL;
+	char perm[3];
+
+
+	// Parsing of arguments
+	if ( argc != 6 )
+		return usage( argv[0] );
+
+#ifndef __APPLE__
+
+	pid = atoi( argv[1] );
+	SCAN_FLAG = atoi( argv[2]);
+	scan_number = atoi (argv[3]);
+	char* file_name  = argv[4];
+	unsigned char marker_char = atoi(argv[5]); // "the color" of memory painting
+
+	marker = (marker_char << 24) +
+				(marker_char << 16) +
+					(marker_char << 8) +
+						marker_char; // 0xCD converted -> 0xCDCDCDCD
+	cout << "  MemoryScanner: marker_char = " << marker_char << " marker = "
+			<< marker << endl;
+	cout << "  MemoryScanner: scan_flag = " << SCAN_FLAG << endl;
+	switch ( SCAN_FLAG ) {
+		   case 0 :
+			   cout << "MemoryScanner: std output, no file output produced" ;
+	       break;
+
+	       case 1 :
+			   cout << "MemoryScanner: full output of hole statistics and malloc/process memory info into " << file_name << "\n";
+	       break;
+
+	       case 2 :
+	    	   cout << "MemoryScanner: malloc/process memory info output into " << file_name << "\n";
+	       break;
+
+	       default :
+	       // Process for all other cases.
+	    	cout << "MemoryScanner: ERROR - Wrong scan_flag=" << SCAN_FLAG <<" provided.\n";
+	   		return usage( argv[0] );
+
+	}
+
+	cout <<"\n MemoryScanner: scan_number=" << scan_number <<" \n";
+
+
+	//auxiliary buffer for reading bits from proc/mem file
+	   const ms_uint64 aux_buffer_size = 1024; // 4096bytes >> 2 = 1024 size_t elements!
+	   cout << "\n buffer_page_size =" <<  aux_buffer_size <<" bytes "<< endl;
+	   size_t aux_buffer[aux_buffer_size];
+	   //size_t mem_size = addr_end - addr_start;
+
+	   //Declaration of counters
+	   ms_uint64 counter = 0; //  marker pieces ('CDCDCDCD') counter
+	   ms_uint64 block_counter = 0; //  marked blockes ('CDCD...CDCD') counter
+	   ms_uint64 maprange_counter = 0;
+
+	   //Declaration of size variables
+
+	   ms_uint64  maps_total_size = 0; // Total maps in /proc/PID/maps
+	   ms_uint64  mem_total_size = 0; //  Total scanned maps (excluding the ranges with no 'wr' permission)
+	   ms_uint64  block_total_size = 0;// Total holes size
+	   ms_uint64 mapsSize = 0, holesSize = 0; //memSize = 0, ;
+
+	   ms_uint64 malloc_total = 0;
+
+	   //Declaration of Marked block related variables
+	   ms_uint64 block_flag = 0;
+	   ms_uint64 block_size = 0;
+	   ms_uint64  block_start = 0; // auxiliary to remember block start location
+	   size_t* block_ptr = 0;
+	   size_t* block_end_ptr = 0;
+	   size_t* addr = 0;
+
+	   //variables related to the TTree building
+	   ms_uint64  hole_addr = (ms_uint64) (size_t) block_ptr;
+	   ms_uint64  hole_size = (ms_uint64) (size_t) block_size;
+
+
+
+	   //--------------------------------------------------//
+	   // ATTACHING To the pid Process
+	   // the %pid-Process restores operation after the MemoryScanner finishes it's job
+	   //--------------------------------------------------//
+	   cout << "using marker: " << marker << endl;
+	   cout << "halting process: " <<  pid << endl;
+	   result = ptrace( PTRACE_ATTACH, pid, NULL, NULL );
+	   if ( result == -1 ) {
+		  cerr << "	MemoryScanner: ERROR - cannot attach to the " << pid << " process \n";
+	      exit( -1 );
+	   }
+	   waitid( P_PID, pid, infop, WSTOPPED );
+
+	   //------------------------------------------------------//
+	   // READING /proc/%PID/status file
+	   //------------------------------------------------------//
+	   char line [128]; /* or other suitable maximum line size */
+	   char head_buffer[6];//char* head_buffer;
+	   char tail_buffer[10];//char* tail_buffer;
+	   snprintf( statusfile, 128, "/proc/%u/status", pid );
+	   statusf = fopen ( statusfile, "r" );
+	   cout << "opened /proc/" << pid << "/status file \n";
+
+	   ms_uint32 tag_value;
+	   ms_uint32 VmSize, VmLck, VmRSS, VmData, VmStk, VmExe, VmLib;
+
+	   if ( statusf != NULL ){
+		   while ( fgets ( line, sizeof line, statusf ) != NULL) /* read a line */{
+			   sscanf( line, "%5s %u %9s", head_buffer, &tag_value, tail_buffer);
+			   //cout <<"h_buffer=" << head_buffer << " tag_value=" << tag_value << " t_buffer=" << tail_buffer << "\n";
+			   if (strncmp(head_buffer, 		"VmSize",5) == 0){
+				   VmSize = tag_value;
+			   } else if (strncmp(head_buffer, 	"VmLck", 5) == 0){
+				   VmLck = tag_value;
+		   	   } else if (strncmp(head_buffer, 	"VmRSS", 5) == 0){
+				   VmRSS = tag_value;
+		   	   } else if (strncmp(head_buffer, 	"VmData",5) == 0){
+				   VmData = tag_value;
+		   	   } else if (strncmp(head_buffer, 	"VmStk", 5) == 0){
+				   VmStk = tag_value;
+		   	   } else if (strncmp(head_buffer, 	"VmExe", 5) == 0){
+				   VmExe = tag_value;
+		   	   } else if (strncmp(head_buffer, 	"VmLib", 5) == 0){
+				   VmLib = tag_value;
+		   	   }
+		   }
+		   fclose ( statusf );
+	   }
+	   else{
+			perror ( statusfile); /* why didn't the file open? */
+	   }
+	   cout << "VmSize=" << VmSize << " VmRSS=" << VmRSS << " VmData=" << VmData
+		   << "VmStk=" << VmStk << "VmExe=" << VmExe << "VmLib=" << VmLib << endl;
+
+
+
+	   //---------------------------------------------------------//
+	   // READING /proc/%PID/maps file
+	   //---------------------------------------------------------//
+	   snprintf( mapfile, 128, "/proc/%u/maps", pid );
+	   maps = fopen( mapfile, "r" );
+	   if( ! maps ) {
+		   cerr << " MemoryScanner: ERROR - accessing /proc/" << pid <<"/maps file \n";
+		   exit( -1 );
+	   }
+	   cout << "opened mapfile:" << mapfile << "\n";
+
+	   //-------------------------------------------------------//
+	   // Handle to /proc/%PID/mem file
+	   //-------------------------------------------------------//
+	   snprintf( memfile, 128, "/proc/%u/mem", pid );
+	   mem = open( memfile, O_RDONLY, NULL );
+	   if ( mem == -1 ) {
+		   cerr << " MemoryScanner: ERROR - accessing /proc/" << pid << "/mem file \n";
+		   exit( -1 );
+	   }
+	   cout << "opened memfile: " << memfile << endl;
+
+
+	   // ROOT Declarations
+	   TFile *memFile ;
+	   TTree *memTree;
+	   TTree *infoTree;
+
+	   if (scan_number == 0){
+	     cout << " Prepare the memFile = " << file_name << "\n";
+		   TTree *mallocTree;
+
+		   memFile = new TFile(file_name, "recreate");
+
+		   // create hole statistics tree and it's branches:
+		   // start_addr,end_addr, scan_number, marker_char
+		   memTree = new TTree("holeTree","memory_holes_data");
+		   memTree->Branch("hole_addr", &hole_addr,"hole_addr/i");
+		   memTree->Branch("hole_size", &hole_size, "hole_size/i");
+		   memTree->Branch("scan_number",&scan_number, "scan_number/s");
+		   memTree->Branch("hole_marker", &marker, "marker/i");
+
+
+		   // create process memory usage + hole info tree and it's branches:
+		   infoTree = new TTree("infoTree","memory_usage_statistics");
+		   infoTree->Branch("total_hole_memory", &holesSize,"hole_mem/i");
+		   infoTree->Branch("total_hole_number", &block_counter,"hole_number/i");
+		   infoTree->Branch("hole_marker", &marker, "hole_marker/i");
+		   infoTree->Branch("total_maps_memory", &mapsSize, "maps_memory/i");
+		   infoTree->Branch("VmSize", 	&VmSize,"vmsize/i");
+		   infoTree->Branch("VmLck", 	&VmLck, "vmlck/i");
+		   infoTree->Branch("VmRSS", 	&VmRSS,	"vmrss/i");
+		   infoTree->Branch("VmData", 	&VmData,"vmdata/i");
+		   infoTree->Branch("VmStk", 	&VmStk,	"vmstk/i");
+		   infoTree->Branch("VmExe", 	&VmExe, "vmexe/i");
+		   infoTree->Branch("VmLib", 	&VmLib, "vmlib/i");
+		   infoTree->Branch("scan_number", &scan_number, "scan_number/s");
+
+		   // create malloc info tree and it's branches:
+		   mallocTree = new TTree("mallocTree","malloc_statistics");
+		   mallocTree->Branch("malloc_sbrk",  &malloc_total, "sbrk/i");
+		   mallocTree->Branch("malloc_mmap",  &malloc_total, "mmap/i");
+		   mallocTree->Branch("malloc_inuse", &malloc_total, "inuse/i");
+		   mallocTree->Branch("malloc_free",  &malloc_total, "free/i");
+		   mallocTree->Branch("scan_number",  &scan_number,  "scan_number/s");
+
+		   mallocTree->Fill();
+		   mallocTree->Print();
+		   mallocTree->Write();
+	   } else {
+	     cout << " Update the memFile = " << file_name << "\n";
+		   memFile = TFile::Open(file_name, "update");
+		   memTree = (TTree*)memFile->Get("holeTree");
+		   infoTree = (TTree*)memFile->Get("infoTree");
+
+		   //bind variables to the memTree  for further update/filling
+		   memTree->SetBranchAddress("hole_addr", &hole_addr);
+		   memTree->SetBranchAddress("hole_size",  &hole_size);
+		   memTree->SetBranchAddress("scan_number",&scan_number);
+		   memTree->SetBranchAddress("hole_marker", &marker);
+
+		   //bind variables to the infoTree for further update/filling
+		   infoTree->SetBranchAddress("total_hole_memory", &holesSize);
+		   infoTree->SetBranchAddress("total_hole_number", &block_counter);
+		   infoTree->SetBranchAddress("total_maps_memory", &mapsSize);
+		   infoTree->SetBranchAddress("hole_marker", &marker);
+		   infoTree->SetBranchAddress("VmSize", &VmSize);
+		   infoTree->SetBranchAddress("VmLck", 	&VmLck);
+		   infoTree->SetBranchAddress("VmRSS", 	&VmRSS);
+		   infoTree->SetBranchAddress("VmData", &VmData);
+		   infoTree->SetBranchAddress("VmStk", 	&VmStk);
+		   infoTree->SetBranchAddress("VmExe", 	&VmExe);
+		   infoTree->SetBranchAddress("VmLib", 	&VmLib);
+		   infoTree->SetBranchAddress("scan_number", &scan_number);
+	   }
+
+
+
+
+	   //----------------------------------------------------//
+	   //Main Part: The actual memory scanning, first read /proc/%pid/maps file
+	   //Then scan /proc/%pid/mem for marked holes
+	   //----------------------------------------------------//
+	   size_t len = 0;
+	   while (getline(&buffer, &len, maps) > 0) {
+	      sscanf( buffer, "%x-%x %2s", &addr_start, &addr_end, perm );
+	      maps_total_size += (addr_end - addr_start);
+
+	      if ( strcmp( perm, "rw" ) != 0 ){
+	         continue;
+	      }
+	      //cout << "addr_start=" << hex << addr_start << " addr_end=" << hex << addr_end << " prm=" << perm << "\n";
+
+	      maprange_counter++;
+	      mem_total_size += (addr_end - addr_start);
+	      //mem_size = addr_end - addr_start;
+
+	      addr = (size_t*) (unsigned long) addr_start;
+
+		   switch ( SCAN_FLAG ) {
+			   case 0 :
+		    	 cout <<"Maps: " << hex << addr_start
+					  << "-"	 << hex << addr_end
+					  << " size=" << addr_end -addr_start << "/n";
+		       break;
+
+		       case 1 :
+			    /*cout <<"Maps: " << hex << addr_start
+						  << "-"	 << hex << addr_end
+						  << " size=" << addr_end -addr_start << "/n";*/;
+		       break;
+
+		       case 2 :
+		    	// cout << "Maps: " << hex << addr_start
+		       break;
+
+		       default :
+		       ;// Process for all other cases.
+		   }
+	      //these are auxiliary flags and variables to define the-size of CDCDCDCD and PINNED blocks
+	      //CD blocks parameters
+	      block_flag = 0;
+	      block_size = 0;
+	      block_ptr = 0;
+	      block_end_ptr = 0;
+	      result = 0;
+
+	    /* scan /proc/%pid/mem for marked holes */
+	      while ( (ms_uint64) (size_t) addr < addr_end  &&  result != -1) {
+
+				/*for (i=0;  i<aux_buffer_size; i++)
+					aux_buffer[i] = 0;*/
+
+				result = pread( mem, &aux_buffer, sizeof(aux_buffer), (ms_uint64) (size_t) addr );
+				if (result == -1){
+					//cerr << " MemoryScanner: ERROR - reading mem at address" << addr << "\t" <<  "error=" << errno << " " << strerror(errno) << "\n";
+					continue ;
+				} else if (result == 0){
+					cerr << " MemoryScanner: WARNING - zero bytes read from mem at address" << addr <<"\n";
+					continue ;
+				}
+
+				int  i;
+
+				for (i=0; i<result; i++){
+						if ( aux_buffer[i] == marker ) {
+							//Here block_flag==0 defines the beginning of the 'CDCDCDCD' memory block
+						   if (block_flag==0) {//cout << "found CDCDCDCD block: " << endl;
+							   block_start = counter;
+							   block_ptr = addr + i;
+							   block_counter++; // 'CDCDCDCD' block counter
+							   block_flag=1; // forthcoming consecutive 'CDCDCDCD' are not the beginning
+						   }
+						   counter ++; //counter of 'CDCDCDCD' pieces
+						}else { //Here block_flag==1 defines the end of the 'CDCDCDCD' memory block
+
+							//this condition for Tcmalloc marking of freed memmory
+							if (block_flag == 1) {
+								if (aux_buffer[i] == size_mark){
+									if ((aux_buffer[i+2] == size_mark) && (aux_buffer[i+1]!=size_mark && aux_buffer[i+1] > 0)){
+										if (aux_buffer[i+1] < 65000000)
+											counter += aux_buffer[i+1]/4 - 2;
+									}
+								}
+							   block_flag = 0;
+							   block_size = counter - block_start;
+							   block_end_ptr = block_ptr + block_size;
+							   //block_size=block_size*sizeof(size_t);
+							   block_total_size +=  block_size;
+							   hole_addr = (ms_uint64 ) (size_t) block_ptr;
+							   //hole_end_addr =   (ms_uint64 ) block_end_ptr;
+							   //hole_size = hole_end_addr - hole_addr;
+							   hole_size = block_size*sizeof(size_t);
+
+							   switch ( SCAN_FLAG ) {
+							     case 0 :
+									   cout <<"C:\t" << hex << block_ptr <<"-" << hex << block_end_ptr ;
+									   cout << " size=" << block_size;
+									   cout << " counter="<< counter << "\n";
+							     break;
+
+							     case 1 :
+									   memTree -> Fill();
+							     break;
+							     case 2 :
+									  /*if(scan_number < report_scan_number)
+										  memTree -> Fill()*/;
+								 break;
+
+							     default :
+							       ;// Process for all other cases.
+							   }
+
+						   }
+						}//if
+					}//for
+					addr += aux_buffer_size;
+			  }//inner-while-end
+
+	     //cout << "hs=" << dec << 4*block_total_size << " c=" << 4*counter << " map_range=" << hex << (size_t*) addr_start << "-" << (size_t*)addr_end << " map_size=" << dec << addr_end - addr_start << " len= "<< len<<"\n";
+	     len = 1;
+	   }//outer-while-end
+
+
+//FINISHED SCANNING of the MEMORY
+	   close( mem );
+	   fclose( maps );
+	   cout << "resuming process:" << pid << endl ;
+
+	   result = ptrace( PTRACE_DETACH, pid, NULL, NULL );
+	   if ( result == -1 ) {
+		  cerr << "MemoryScanner: ERROR " << errno << " " << strerror(errno) << "\n";
+	      exit( -1 );
+	   }
+
+
+	   switch ( SCAN_FLAG ) {
+	     case 0 :
+	       // Process for scan_flag = 0
+			   cout <<"TOTAL FOUND for scan_number: " 			<< scan_number << "\n";
+			   cout << maprange_counter << " MAP_RANGES scanned"<< "\n";
+			   cout << block_counter 	<< " MARKED-Blocks" 	<< "\n";
+			   cout << counter			<< " MARKED-pieces"		<< "\n";
+			   cout << maps_total_size 	<< "(" << maps_total_size*1.0/(1048576.0)	<< " Mb)- TOTAL MAPS MEMORY SIZE   \n";
+			   cout << mem_total_size 	<< "(" << mem_total_size*1.0/(1048576.0) 	<< " Mb)- TOTAL SCANNED MEMORY SIZE\n";
+			   cout <<4*block_total_size<< "(" << 4.0*block_total_size/(1048576.0)	<< " Mb)- MARKED blocks MEMORY SIZE\n";
+			   cout <<4*counter			<< "(" 	<< 4.0*counter/(1048576.0) 	 		<< " Mb)- MARKED pieces MEMORY SIZE\n";
+
+	     break;
+
+	     case 1: case 2 :
+	       // Process for scan_flag = 1
+			   cout <<"TOTAL FOUND for scan_number: " 			<< scan_number << "\n";
+			   cout << maprange_counter << " MAP_RANGES scanned"<< "\n";
+			   cout << block_counter 	<< " MARKED-Blocks" 	<< "\n";
+			   cout << counter			<< " MARKED-pieces"		<< "\n";
+			   cout << maps_total_size 	<< "(" << maps_total_size*1.0/(1048576.0)	<< " Mb)- TOTAL MAPS MEMORY SIZE   \n";
+			   cout << mem_total_size 	<< "(" << mem_total_size*1.0/(1048576.0) 	<< " Mb)- TOTAL SCANNED MEMORY SIZE\n";
+			   cout <<4*block_total_size<< "(" << 4.0*block_total_size/(1048576.0)	<< " Mb)- MARKED blocks MEMORY SIZE\n";
+			   cout <<4*counter			<< "(" 	<< 4.0*counter/(1048576.0) 	 		<< " Mb)- MARKED pieces MEMORY SIZE\n";
+
+			   memFile->cd();
+			   memTree->Write();
+			   mapsSize = maps_total_size/1024;
+			   holesSize = 4*block_total_size/1024;
+			   infoTree->Fill();
+			   infoTree->Write();
+			   memTree->Delete();
+			   infoTree->Delete();
+			   memFile->Close();
+	      break;
+
+	     default :
+	       // Process for all other cases.
+	    	 memTree->Delete();
+	    	 infoTree->Delete();
+	    	 memFile->Close();
+	   }
+#endif
+
+	   return 0;
+}
+
+
diff --git a/Control/HeapMon/src/tcmalloc_dummy.c b/Control/HeapMon/src/tcmalloc_dummy.c
new file mode 100644
index 0000000000000000000000000000000000000000..3122b45a8c3e70873602272f8616b13c37bc9cf0
--- /dev/null
+++ b/Control/HeapMon/src/tcmalloc_dummy.c
@@ -0,0 +1,26 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <gperftools/malloc_hook_c.h>
+
+
+size_t MallocExtension_GetAllocatedSize(void* p){
+	return 0;
+}
+
+MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {
+	//printf("dummy");
+  return 0;
+}
+
+MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {
+	//printf("dummy");
+	return 0;
+}
+
+void MallocExtension_GetStats(char* buffer, int buffer_length){
+ return ;
+}
+
+