# I'm not sure I'm using caml\_alloc\_custom\_mem correctly

**URL:** <https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112>\
**Category:** Learning\
**Created:** [August 16, 2025, 10:03am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112 "2025-08-16T10:03:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rwmjones](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rwmjones/32/818_2.png) [@rwmjones](https://discuss.ocaml.org/u/rwmjones)\
**Post date:** [August 16, 2025, 10:03am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/1 "2025-08-16T10:03:17Z")

</div>

[https://gitlab.com/nbdkit/libnbd/-/blob/0923235cd595b2885f121586b0bd41b03e7910ea/ocaml/nbd-c.h#L91](https://gitlab.com/nbdkit/libnbd/-/blob/0923235cd595b2885f121586b0bd41b03e7910ea/ocaml/nbd-c.h#L91)

In this code, we’re allocating a custom block that represents a large handle (allocated by a C library). The C handle is actually 9000 bytes (yes, it’s grown a bit in the last 6 years). Only a pointer to the C handle (4 or 8 bytes) is stored inside the custom block.

This code works fine.

I wonder however if I’m using `caml_alloc_custom_mem` correctly here. The documentation, and even the code, is not very clear at all. It seems like maybe the sizeof and 5000 parameters should be swapped?

Or maybe using the function is wrong. `caml_alloc_custom` also lets you hint about the resources needed, so should we use that instead? If so, what’s the difference between the `size`, `mem` and `max` parameters of this function?

---

<div class="post-metadata">

**Author:** ![rwmjones](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rwmjones/32/818_2.png) [@rwmjones](https://discuss.ocaml.org/u/rwmjones)\
**Post date:** [August 16, 2025, 10:42am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/2 "2025-08-16T10:42:04Z")

</div>

I found exactly one other piece of code that calls `caml_alloc_custom_mem`: [postgresql-ocaml/lib/postgresql\_stubs.c at 4c58e6f65e68a9a25873702e52c11564e18b1abb · mmottl/postgresql-ocaml · GitHub](https://github.com/mmottl/postgresql-ocaml/blob/4c58e6f65e68a9a25873702e52c11564e18b1abb/lib/postgresql_stubs.c#L503)

---

<div class="post-metadata">

**Author:** ![kit-ty-kate](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/kit-ty-kate/32/5953_2.png) [@kit-ty-kate](https://discuss.ocaml.org/u/kit-ty-kate)\
**Post date:** [August 16, 2025, 11:01am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/3 "2025-08-16T11:01:56Z")

</div>

In case that helps there are also examples in the compiler itself:

> <https://github.com/ocaml/ocaml/blob/afc8eb8df192ffeed6a630a14c7ca806670ccd60/runtime/blake2.c#L211>

> <https://github.com/ocaml/ocaml/blob/afc8eb8df192ffeed6a630a14c7ca806670ccd60/runtime/bigarray.c#L250>

---

<div class="post-metadata">

**Author:** ![rwmjones](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rwmjones/32/818_2.png) [@rwmjones](https://discuss.ocaml.org/u/rwmjones)\
**Post date:** [August 16, 2025, 11:11am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/4 "2025-08-16T11:11:48Z")

</div>

Thanks - I think looking at those examples, we are actually using the API correctly. A question I still have is why `caml_alloc_custom_mem` exists at all, what is the difference from `caml_alloc_custom`?

---

<div class="post-metadata">

**Author:** ![silene](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/silene/32/2707_2.png) [@silene](https://discuss.ocaml.org/u/silene)\
**Post date:** [August 16, 2025, 2:37pm UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/5 "2025-08-16T14:37:37Z")

</div>

`caml_alloc_custom` was the original function. But it was really tedious to use, as you had to guess what to pass as the fourth argument, and more often than not, people would get this argument wrong, thus causing runtime performances to drop heavily. (I am looking at you, iterators in Lablgtk!) `caml_alloc_custom_mem` gives a much more intuitive meaning to the arguments (though a bit less flexible), which avoids the issue entirely.

---

<div class="post-metadata">

**Author:** ![rwmjones](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rwmjones/32/818_2.png) [@rwmjones](https://discuss.ocaml.org/u/rwmjones)\
**Post date:** [August 16, 2025, 7:57pm UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/6 "2025-08-16T19:57:49Z")

</div>

FWIW I added a function to the C library to estimate the size of the handle, and modified the OCaml binding to this:

[https://gitlab.com/nbdkit/libnbd/-/blob/cedf3f07c1012a63487b96ba8ee9751e0252738f/ocaml/nbd-c.h#L80-L99](https://gitlab.com/nbdkit/libnbd/-/blob/cedf3f07c1012a63487b96ba8ee9751e0252738f/ocaml/nbd-c.h#L80-L99)

---

<div class="post-metadata">

**Author:** ![jjb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jjb/32/2713_2.png) [@jjb](https://discuss.ocaml.org/u/jjb)\
**Post date:** [August 17, 2025, 10:17am UTC](https://discuss.ocaml.org/t/im-not-sure-im-using-caml-alloc-custom-mem-correctly/17112/7 "2025-08-17T10:17:39Z")

</div>

Another important point is that the GC pacing specified by `caml_alloc_custom_mem` is user-adjustable using the `custom_major_ratio`, `custom_minor_ratio`, and `custom_minor_max_size` parameters via `Gc.set`, giving `caml_alloc_custom_mem` an advantage when used in libraries.

For controlling resource usage that isn’t memory but is still dictated by the GC lifetime of a custom block (I’m not saying that is a good idea), then `caml_alloc_custom` gives better control. And the parameters of `caml_alloc_custom_mem` are unitless but interpreted as proportional to the heap size, so make less sense for non-memory resources.

For info, there are also uses of `caml_alloc_custom_mem` in [Z3](https://github.com/Z3Prover/z3/blob/a121e6c6e95c60f50d1561f03762805dabc969e1/src/api/ml/z3native_stubs.c.pre#L92). In that situation custom blocks are used to manage reference-counted C objects. It is not possible to known the amount of off-heap memory that freeing such a custom block will release, but the parameters are still useful as scaling factors to adjust the GC pacing.
