[mcclim-devel] how to track down apparent memory leaks in drawing?

John Morrison john.nmi.morrison at gmail.com
Fri Nov 2 21:13:34 UTC 2012


Hi All;

tl:dr; slightly revised drawing-benchmark demo (attached) from
quicklisp mcclim shows increased (leaked?) memory usage.

I am using McCLIM to deal with PostGIS (FC16, x86_64).  It appeared
that drawing vector GIS data using draw-line* leaked memory.

After doing the obvious things (see below), I slightly modified the
clim-demo::drawing-benchmark app to try and produce the smallest code
that exhibits the behavior:

1. draw lines instead of either rectangles or text
2. for 20 seconds rather than 1
3. print SBCL's (room) into the window (make your mapped window tall)
4. run a (sb-ext:gc)
5. print (room) again

lather, rinse, and repeat, by hitting the "Run" button.

I obviously didn't use the presentation system in my program (as I
presumed it would hold onto output records, etc.).  I commented out
the single draw-line* form, and that enabled my program to traverse
the entire (rather large) GIS vector dataset with no perceptible
increase in memory usage (according to the "top" UNIX utility rather
than (room).  I updated to today's SBCL (maybe it's a bug that's been
fixed), but I still observed the increasing memory usage.

Questions:

(a) Should I try any of the several forked McCLIMs mentioned recently?
Has any of them had significant work in the simple drawing area?

(b) Can anybody tell me anything that might shorten the hunt?

Thanks!!!

-jm

-- 
--- John Morrison
--- john.nmi.morrison at gmail.com
-------------- next part --------------
;;; -*- Mode: Lisp; -*-

;;;  (c) 2006 David Lichteblau (david at lichteblau.com)

;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Library General Public
;;; License as published by the Free Software Foundation; either
;;; version 2 of the License, or (at your option) any later version.
;;;
;;; This library is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; Library General Public License for more details.
;;;
;;; You should have received a copy of the GNU Library General Public
;;; License along with this library; if not, write to the 
;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
;;; Boston, MA  02111-1307  USA.

(in-package :clim-demo)

(define-application-frame drawing-benchmark ()
    ()
  (:panes
   (canvas :application
	   :min-width 600
	   :incremental-redisplay nil
	   :display-time nil)
   (mode
    (with-radio-box ()
      (radio-box-current-selection
       (make-pane 'toggle-button :label "lines" :id :lines))
      (make-pane 'toggle-button :label "rectangle" :id :rectangle)
      (make-pane 'toggle-button :label "text" :id :text)))
   (ink
    (with-radio-box ()
      (radio-box-current-selection
       (make-pane 'toggle-button :label "random" :id :random))
      (make-pane 'toggle-button :label "red" :id +red+)
      (make-pane 'toggle-button :label "flipping ink" :id +flipping-ink+))))
  (:layouts
   (default
       (vertically ()
	 (horizontally ()
	   (labelling (:label "Mode") mode)
	   (labelling (:label "Ink") ink))
	 canvas))))

(defmethod run-drawing-benchmark (frame stream)
  (setf (stream-recording-p stream) nil)
  (window-clear stream)
  (let* ((width (rectangle-width (sheet-region stream)))
	 (height (rectangle-height (sheet-region stream)))
	 (mode (gadget-id (gadget-value (find-pane-named frame 'mode))))
	 (ink (gadget-id (gadget-value (find-pane-named frame 'ink))))
	 (itups internal-time-units-per-second)
	 (n 0)
	 (start (get-internal-real-time))
	 (stop (+ start (* 20 itups))))
    (do ()
	((>= (get-internal-real-time) stop))
      (incf n)
      (let ((ink
	     (if (eq ink :random)
		 (clim:make-rgb-color (random 1.0d0)
				      (random 1.0d0)
				      (random 1.0d0))
		 ink)))
	(ecase mode
	  (:lines
	    (draw-line* stream
			     10 10 40 40
			     :ink ink))
	  (:rectangle
	    (draw-rectangle* stream
			     10 10 (- width 10) (- height 10)
			     :ink ink
			     :filled t))
	  (:text
	    (dotimes (x 10)
	      (draw-text* stream
			  "Bla blub hastenichgesehen noch viel mehr Text so fuellen wir eine Zeile."
			  0
			  (* x 20)
			  :ink ink))))))
    (finish-output stream)
    (medium-finish-output (sheet-medium stream))
    (climi::port-force-output (car climi::*all-ports*))
    (setf stop (get-internal-real-time))
    (window-clear stream)
    (setf (stream-recording-p stream) t)
    (room)
    (sb-ext:gc)
    (room)
    (format stream "Score: ~A operations/s~%"
	    (float (/ n (/ (- stop start) itups))))))

(define-drawing-benchmark-command (com-quit-drawing-benchmark :menu "Quit") ()
  (frame-exit *application-frame*))

(define-drawing-benchmark-command (com-run-drawing-benchmark :menu "Run") ()
  (run-drawing-benchmark *application-frame*
			 (frame-standard-output *application-frame*)))


More information about the mcclim-devel mailing list