Thank you very much for the fast, clear, and detailed answer :)

On Fri, 1 Nov 2019 at 15:08, Ian Lance Taylor <i...@golang.org> wrote:

> On Fri, Nov 1, 2019 at 6:31 AM Tom Payne <twpa...@gmail.com> wrote:
> >
> > cgo is often used to provide bindings to C libraries. Any memory
> allocated in the C library is not visible to Go, so Go does not have an
> accurate view of the program's memory usage and does not run the garbage
> collector or any finalizers often enough. Consequently, memory usage for a
> Go server that uses cgo heavily can grow very large, with Go itself being
> utterly unaware of it.
> >
> > If the C functions allocate memory, historically you could set a
> finalizer to free the memory sometime after there are no remaining
> references to it in Go, as, for example, described in this blog post.
> However, the current Go docs on runtime.SetFinalizer state:
> >
> > > There is no guarantee that finalizers will run before a program exits,
> so typically they are useful only for releasing non-memory resources
> associated with an object during a long-running program.
> >
> > Are there any other ways to automatically release memory resources
> associated with an object? Or telling Go's memory manager that the small
> object it sees in the Go world is but the tip of an iceberg of memory
> allocated in the C world and therefore should be finalized?
> >
> > Not-good options include:
> > - Requiring the programmer to make explicit calls to free the memory
> resources when they believe the object is no longer needed, but this takes
> us back to the painful world of C's manual memory management and is easy to
> get wrong.
> > - Padding Go objects associated with C memory resources with large,
> unused fields (e.g. an [1024]byte) in the hope that the Go garbage
> collector will be more likely to finalize and free them when they are
> unused.
> > - Avoiding cgo in any server code.
> >
> > Are there any good options?
>
>
> If you are using C code, you are using C's memory resource policy.  So
> the best approach is to use explicit calls to free.  I agree that that
> takes you back to the painful world of C's manual memory management,
> but, after all, if you are using C then you can't pretend that you are
> not using C.
>
> That said, although Go is careful not to promise that it will actually
> execute finalizers, in practice it does run them.  Padding the Go
> object won't make any difference as to when a finalizer is run.  It
> will be run in the next full GC cycle after the Go value is no longer
> referenced.  If there are times when the program knows that there is a
> lot of C memory that is no longer required, it can help by calling
> runtime.GC itself.
>
> In practice I think the best approach is a hybrid: free the C memory
> explicitly, but also add a finalizer.  In the finalizer, free the C
> memory, and log the fact that you are doing so, along with any
> information that will help identify where the C memory was allocated.
> Then periodically check your logs for cases where the finalizer ran,
> and add the necessary calls to explicitly free the C memory manually.
> Of course, when you free the C memory manually, don't forget to clear
> the finalizer.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAHY_QbR2NB1FFobtTW6dkXN9h-Zj5uw3bfodVnFzghL_1%3DdUJg%40mail.gmail.com.

Reply via email to