[racket] Freeing FFI resources

From: Neil Toronto (neil.toronto at gmail.com)
Date: Wed Oct 13 13:51:08 EDT 2010

Eli Barzilay wrote:
> But of course if the problem is the original one in this thread, where
> each C string eventually needs to be converted to a Racket string,
> then there's little point in holding on to a pointer instead of
> converting it immediately (and freeing the C pointer).

True, dat.

> With this code:
> 
>   #lang racket
>   (require ffi/unsafe)
>   (define bytes/free
>     (make-ctype _bytes
>                 #f ; a Racket bytes can be used as a pointer
>                 (lambda (b)
>                   (register-finalizer b free)
>                   b)))
>   (define strdup
>     (get-ffi-obj 'strdup #f (_fun _bytes -> bytes/free)))
>   (for ([i (in-range 1000000000)]) (strdup #"bleh"))
> 
> I get memory at around 200mb; with a `free' instead of the finalizer,
> it's around 130mb.

That tracks well with my experience. As I made a ctype for them, I found 
there were two allocations for each Racket-managed struct, each about 
the same size as the Racket-managed one. So yeah, it's easy to triple 
Racket's memory consumption without it knowing.

Might be a good idea to make a note in the docs. And possibly include 
Jon's _out-string example, or abstract it, as this kind of thing 
probably comes up a lot. I cleaned up some cruft by adapting it for a 
string-returning function in my own FFI.

Neil T



Posted on the users mailing list.