image thumbnail

Scrolling Memory Monitor

by

 

25 Oct 2012 (Updated )

Displays recent history of Matlab & Java memory usage.

memtracker(varargin)
% USAGE:
%    memtracker
%       Creates memtracker figure (docked by default)
%
%    memmtracker pause
%       Pauses the memory tracker from updating
%    
%    memmtracker resume
%       Resumes memory tracker updating
%
%    memtracker('SetUpdateRate',ur)
%        Sets update rate to specified interval (seconds) (default: 0.5 sec)
%
%    memtracker('SetBufferSize',size)
%        Sets the buffer size to specified size (number of elements) (default: 500)
%    
%    memtracker('SetPlotProps', ... )
%        Applies specified property/value pairs to the line objects
%
%    memtracker('SetAxProps', ... )
%        Applies specified property/value pairs to the axes objects
%
%    memtracker('SetFigProps', ... )
%        Applies specified property/value pairs to the figure
%
%    memtracker dock
%        Dock the memtracker figure
%
%    memtracker undock
%        Undock the memetracker figure
%
% 
%   Author: Jesse Hopkins
%   Date:   Oct. 25 2012
%

function memtracker(varargin)
	persistent t;
	persistent f;
	persistent log_matlab;
	persistent log_java;
	persistent idx;
	persistent indexer;
	persistent p_matlab;
	persistent p_java;
	persistent ax_matlab;
	persistent ax_java;
	persistent minUpdateRate;
	persistent JAVAMAX;
	persistent bufsize;
	
	%protect from clearing of persistent variables
	if ~mislocked
		mlock;
	end
	
	if isempty(f) || isempty(t) || ~ishandle(f) || ~isa(t,'timer')
		if isa(t,'timer') && isvalid(t)
			stop(t);
			delete(t);
		end
		if ishandle(f)
			delete(f);
		end
		
		JAVAMAX = java.lang.Runtime.getRuntime.maxMemory;
		minUpdateRate = 0.1;
		bufsize = 500;
		log_matlab = nan(bufsize,1);
		log_java = nan(bufsize,1);
		idx = 1;
		indexer = [2:bufsize bufsize];
		
		%init
		t = timer('ExecutionMode','fixedRate','Period',0.5,'TimerFcn',@update);
		f = figure('Name','Mem Monitor',...
			'NumberTitle','off',...
			'HandleVisibility','off',...
			'Toolbar','none', ...
			'Menubar','none',...
			'WindowStyle','docked',...
			'CloseRequestFcn',@cleanup);
		
		ax_matlab = subplot(2,1,1,'parent',f);
		ax_java   = subplot(2,1,2,'parent',f);
		p_matlab = plot(ax_matlab,1:length(log_matlab),log_matlab,'linewidth',2);
		p_java    = plot(ax_java,1:length(log_java),log_java,'linewidth',2);
		ylabel(ax_matlab,'Matlab (MB)','FontSize',6);
		ylabel(ax_java,'Java (MB)','FontSize',6);
		grid(ax_matlab,'on');grid(ax_java,'on');
		set(ax_matlab,'XTickLabel','','FontSize',6);
		set(ax_java,'XTickLabel','','FontSize',6);
		h_garbageCollect = uicontrol('parent',f,'style','pushbutton','String','Collect Garbage','callback','java.lang.System.gc()','position',[20 20 120 20]);

		start(t);
	end
	
	if nargin >= 1
		switch lower(varargin{1})
			case 'pause'
				stop(t);
			case 'resume'
				start(t);
			case 'dock'
				set(f,'WindowStyle','docked');
			case 'undock'
				set(f,'WindowStyle','normal')
			case 'setupdaterate'
				if varargin{2} < minUpdateRate
					warning('memtracker:toofast','Specified Update Rate (%d) is less than minimum (%d)',varargin{2},minUpdateRate);
				else
					stop(t);
					set(t,'Period',varargin{2});
					start(t);
				end
			case 'setbuffersize'
				stop(t);
				bufsize = varargin{2};
				log_matlab = nan(bufsize,1);
				log_java = nan(bufsize,1);
				indexer =  [2:bufsize bufsize];
				set(p_matlab,'XData',1:length(log_matlab),'YData',log_matlab);
				set(p_java,'XData',1:length(log_java),'YData',log_java);
				idx = 1;
				start(t);
			case 'setplotprops'
				stop(t);
				set(p_matlab,varargin{2:end});
				set(p_java,varargin{2:end});
				start(t);
			case 'setaxprops'
				stop(t);
				set(ax_matlab,varargin{2:end});
				set(ax_java,varargin{2:end});
				start(t);
			case 'setfigprops'
				stop(t);
				set(f,varargin{2:end});
				start(t);
		end
	end
	
	function update(src,eventdata)
		t1 = tic;
		j = java.lang.Runtime.getRuntime.freeMemory;
		j = (JAVAMAX - j)/1024/1024;
		m = memory;
		m = m.MemUsedMATLAB/1024/1024;
		if idx == bufsize
			log_matlab = log_matlab(indexer);
			log_matlab(idx) = m;
			
			log_java = log_java(indexer);
			log_java(idx) = j;
		else
			log_matlab(idx) = m;
			log_java(idx)   = j;
			idx = idx + 1;
		end
		set(p_matlab,'YDATA',log_matlab);
		set(p_java,'YDATA',log_java);
		
		%format the ticks as integers
		set(ax_matlab,'YTickLabel',sprintf('%d|',round(get(ax_matlab,'YTick'))));
		set(ax_java,'YTickLabel',sprintf('%d|',round(get(ax_java,'YTick'))));

		%Record how long it took to execute this callback.  Set the minimum rate to twice that
		minUpdateRate = toc(t1)*2;
	end

	function cleanup(src,eventdata)
		try %#ok<TRYNC>: no catch here, just close the figure if there's an error in this.
			stop(t);
			delete(t);
		end
		delete(src);
	end
end

 %#ok<*INUSD>

Contact us