Take the 2-minute tour ×

I have a binding to a C library.

(define-cstruct _rect
  ([x _int]
   [y _int]
   [w _int]
   [h _int]))

And I want to use this object in programs.

(require ffi/unsafe
         (rename-in "sdl-structs.rkt"
                    [make-rect _make-rect]))

(module rect racket
  (provide (all-defined-out)))

(define (make-rect x y w h)
  (define new-rect (_make-rect x y w h))

(define (left rect)
  (rect-x rect))

(define (top rect)
  (rect-y rect))


(define (bottom-left rect)
  (values (left rect) (bottom rect)))

(define (bottom-right rect)
  (values (right rect) (bottom rect)))

But there's currently a memory leak. It takes a while to crash, but it still crashes.

(define (eat-memory)
  (define memory (current-memory-use))
  (define (eat-loop)
      (make-rect 0 0 1 1)
      (displayln memory)
      (set! memory (current-memory-use))

I want to have the memory automatically reclaimed, how would I go about doing it? I've looked at the documentation on finalization of memory, but I don't see how that's supposed to be helpful. Wouldn't I need to call each of the functions manually anyway?

share|improve this question
Your eat-memory function looks a little suspicious. Look at how eat-memory calls eat-loop, which calls into... eat-memory again! I think you mean for eat-loop to call itself as eat-loop. Normally, this should still be ok, since the call is a tail call, but if your language settings are trying to produce good stack traces, it may be possible that you're not getting good tail-optimizing behavior out of this particular mutually-recursive loop. –  dyoo Aug 5 '13 at 4:54
@dyoo Are you saying that the code shouldn't normally leak memory? –  Drew Aug 5 '13 at 23:23
I don't believe it should be leaking. I see no internal pointers in your _rect definition, so that shouldn't be causing the GC to get confused. I'd recommend checking with the racket-users mailing list if you can. Unfortunately, I don't have time to help debug this at the moment. :( –  dyoo Aug 5 '13 at 23:38
I changed the eat-memory function to recurse directly, the OOM error still persists. –  Drew Aug 7 '13 at 0:09
Yeah, check with the official racket-users mailing list about this one then. Looks suspicious. Good luck! –  dyoo Aug 7 '13 at 5:46
add comment

1 Answer

up vote 0 down vote accepted

Here's the core of your code, without the extra noise:

#lang racket
(require ffi/unsafe)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(let loop ([n 0])
  (make-rect 0 0 1 1)
  ;; (list 0 0 1 1)
  (displayln (current-memory-use))
  (loop (add1 n)))

If you run it, you'll see what looks like a leak. Now flip the comments to use list and you'll see a similar leak. The thing is that you're printing the memory use after each an every allocation, and it takes a good while to reach a point where the GC starts working. If you change it to do the printout less frequently, you'll see a stable memory. Here's what I run to see this:

#lang racket
(require ffi/unsafe)
(let loop ([n 0])
  (make-rect 0 0 1 1)
  (when (zero? (modulo n 100000)) (displayln (current-memory-use)))
  (loop (add1 n)))

That being said, it is easy to get memory leaks when you're using the unsafe FFI, and you're using a library that might a problem itself, and after all of that, it might be that there's some other bug...

share|improve this answer
add comment

Your Answer


