Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does GHC allocate foreign memory and how does the garbage collector treat it?

This question is about the functions alloca and malloc from Foreign.Marshal.Alloc and newForeignPtr and mallocForeignPtr from Foreign.ForeignPtr. Where does the allocated memory live and how does the garbage collector treat it?

like image 776
phischu Avatar asked Jul 13 '16 10:07

phischu


People also ask

How does Haskell manage memory?

Haskell computations produce a lot of memory garbage - much more than conventional imperative languages. It's because data are immutable so the only way to store every next operation's result is to create new values. In particular, every iteration of a recursive computation creates a new value.

Does Haskell use garbage collection?

The Haskell runtime system employs a generational garbage collector (GC) with two generations 2. Generations are numbered starting with the youngest generation at zero.


2 Answers

The memory pointed to by Ptr a allocated by malloc lives on the heap, as in the C programming language. It is ignored by the garbage collector - you have to manually deallocate it yourself using free, and be careful to never use it again after that.

alloca f does a similar allocation, call f with the pointer, and free the memory after that. The pointer must not be used after f returns.

These routines are not meant to be used in everyday code, but only to interface with other languages, using a C-like interface (FFI). You get precisely the same memory safety guarantees C offers -- which means practically none. As such it is quite dangerous, and should be used with great care.

By comparison, the ForeignPtr-pointed memory still lives on the heap, but will be garbage collected after no more pointers (i.e. Haskell's ForeignPtr a) refer to the memory. Note that, even if garbage collection is used here, this kind of pointers are not risk-free. Indeed, when Haskell has no more live pointers to the memory the runtime will free it, even if that pointer is still live in the foreign language. The programmer must ensure that this will never happen.

like image 75
chi Avatar answered Sep 29 '22 13:09

chi


malloc calls the C malloc(), so it allocates memory on the C heap which you have to free manually. (You can also do that from C with free() if you like.)

alloca and mallocForeignPtr allocate pinned byte arrays, which live on the Haskell pinned heap. The GC will free these automatically when they're no longer needed, but will never move them (since they're pinned) so you can pass their addresses to a C function.

newForeignPtr doesn't seem relevant to your question.

like image 29
Reid Barton Avatar answered Sep 29 '22 14:09

Reid Barton