Are NIF resources meant to be destroyed immediately on GC?

Ben Murphy benmmurphy@REDACTED
Mon Nov 23 21:06:13 CET 2020


You can add a printf() debug to fire when the destructor is called or
use lldb to check. A nif on 22.3.4.11 always has the destructor called
straight away. But maybe the GC acts weird in some situations. Or
maybe on your erlang version part of the function frame is being
incorrectly kept alive. You could try nesting the
function_allocates_large_memory/0 call in another function and not
returning the resource to ensure there can't be a ref to it. Also,
maybe your code thinks its not being destroyed because the erlang
allocator will reuse the allocation if another function creates a
resource of the same size.

On Mon, Nov 23, 2020 at 7:24 PM José Valim <jose.valim@REDACTED> wrote:
>
> Hi everyone,
>
> We are working on some code that allocates large chunks of memory inside a NIF and ties them to a resource (using enif_alloc_resource + enif_make_resource). While running some tests, I noticed that we were holding onto these resources for longer than we wanted to, so we have added calls to erlang:garbage_collect/1. In a nutshell, the code looks like this:
>
> my_nif:function_allocates_large_memory(),
> erlang:garbage_collect(),
> my_nif:check_if_resource_has_been_destroyed().
>
> In our runs, it seems that the resource has not yet been destroyed in most cases. However, if we do add a sleep after garbage collection, then the odds of it being destroyed increases as we increase the sleep interval.
>
> Is this correct? Even if the resource was garbage collected, the destructor may not have been called? Or is this actually a big in our software that we should look deeper into?
>
> Thank you,


More information about the erlang-questions mailing list