[racket] Freeing FFI resources
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