FFI Object Deallocator Not Called

61 views
Skip to first unread message

Bryant Curto

unread,
Nov 5, 2019, 5:14:01 PM11/5/19
to Racket Users
Hello!

I have an FFI object I created with an allocator/deallocator wrapper pair, but the deallocation function never appears to get called.
I'm invoking garbage collection explicitly before shutdown with no success.

Is there something I'm missing? Is there a good way to debug garbage collection decisions?
I saw a configuration flag called --enable-backtrace and am thinking that it might be useful, but am not sure where to start.

Thanks!

Matthew Flatt

unread,
Nov 7, 2019, 8:26:29 AM11/7/19
to Bryant Curto, Racket Users
At Tue, 5 Nov 2019 14:14:00 -0800 (PST), Bryant Curto wrote:
> I have an FFI object I created with an allocator/deallocator wrapper pair,
> but the deallocation function never appears to get called.
> I'm invoking garbage collection explicitly before shutdown with no success.

One catch is that finalization callbacks are run in a separate
(privileged) thread. You may have to interleave `(collect-garbage)`
with `(sync (system-idle-evt))` to trigger finalization.

> Is there something I'm missing? Is there a good way to debug garbage
> collection decisions?
> I saw a configuration flag called --enable-backtrace and am thinking that
> it might be useful, but am not sure where to start.

Yes, building with `--enable-backtrace` and using `dump-memory-stats`
to get traces can be helpful. The implementation is a little flaky, but
it normally works.

Backtrace support in Racket CS is always enabled and it's not flaky, so
trying with Racket CS is another option.


Matthew

Bryant Curto

unread,
Nov 7, 2019, 1:02:12 PM11/7/19
to Racket Users
Thank you Matthew for your response!

>One catch is that finalization callbacks are run in a separate (privileged) thread.
To clarify, do you mean a Racket thread or an OS thread?

Sage Gerard

unread,
Nov 7, 2019, 3:16:38 PM11/7/19
to Bryant Curto, Racket Users
To add: Is it wise to put (begin (sync (system-idle-evt)) (collect-garbage)) in a flush callback on the exit handler's plumber?

~slg


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.

Matthew Flatt

unread,
Nov 7, 2019, 5:14:17 PM11/7/19
to Bryant Curto, Racket Users
At Thu, 7 Nov 2019 10:02:11 -0800 (PST), Bryant Curto wrote:
> > One catch is that finalization callbacks are run in a separate
> > (privileged) thread.
>
> To clarify, do you mean a Racket thread or an OS thread?

In a Racket thread.

Matthew Flatt

unread,
Nov 7, 2019, 5:19:40 PM11/7/19
to Sage Gerard, Bryant Curto, Racket Users
At Thu, 07 Nov 2019 20:16:29 +0000, Sage Gerard wrote:
> To add: Is it wise to put (begin (sync (system-idle-evt)) (collect-garbage))
> in a flush callback on the exit handler's plumber?

I should have clarified that if you need a finalizer to run when Racket
shuts down, then finalization alone is not a good choice. Instead,
`register-finalizer-and-custodian-shutdown` may be the way to go.

A `(begin (sync (system-idle-evt)) (collect-garbage))` is useful when
exploring a potential leak, but it's not reliable for making sure that
everything that could possibly be finalized is finalized. There's just
not a good way to do that with finalizers. But custodians provide
predictable shutdown behavior.

So, adding `(begin (sync (system-idle-evt)) (collect-garbage))` to a
plumber does not seem useful, because the effect is not predictable
enough to rely on.

Reply all
Reply to author
Forward
0 new messages