Question

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))
  new-rect)

(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)
    (begin
      (make-rect 0 0 1 1)
      (displayln memory)
      (set! memory (current-memory-use))
      (eat-loop)))
  (eat-loop))

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?

Was it helpful?

Solution

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)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(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...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top