Comments on SegmentAllocator and ResourceScope

Stig Rohde Døssing stigdoessing at
Mon May 17 18:40:15 UTC 2021

Thanks for the explanations.

That hardcoded default size seems reasonable enough to me as it's a
> trade off between various issues like system memory fragmentation,
> overheads, performance, and simplicity.
> The default size makes sense, but the SegmentAllocator example in JEP 412
says that memory allocation can be a bottleneck, and uses the unbounded
arena allocator in an example where many small off-heap arrays are sliced
off a block. This led me to believe that using an arena allocator should be
encouraged in any case where the application needs to allocate many
off-heap segments at once, but I am now getting the impression that this
was not what this example was intended to communicate, and the arena
allocator is only useful when the slices are very small (less than 2KB in
size), and there is no reason to use it when creating larger segments. Is
this correctly understood?

I read that section as saying you need to use
> the handle methods to ensure proper behaviour, exceptions would then
> expose code faults
> Okay, so Handles are not a coordination utility, they are a guard
rail/debugging utility that makes the closing thread throw an exception if
"close" is called inappropriately, rather than letting the close happen,
and then potentially failing in an uglier way in the thread using the
resource, or further downstream. Right?

I don't see anything preventing us from overriding defaults
> Sure. If specifying a block size as a parameter to the unbounded arena
allocator is something you turn out to want to add later, you might run
into a bit of awkwardness with the two factory functions in
SegmentAllocator. They are both named "arenaAllocator", even though one is
for bounded allocators and the other is not.

The interfaces allow to implement memory pools, as is. See this attempt
> Thank you, exactly what I was hoping for.

Handle not being AutoCloseable makes sense, thanks for explaining.

Den man. 17. maj 2021 kl. 12.26 skrev Maurizio Cimadamore <
maurizio.cimadamore at>:

> On 17/05/2021 07:47, Michael Zucchi wrote:
> > Looks a bit odd but note that the original segment is still the
> > current one for subsequent allocations so it will still be used for
> > other small allocations, it probably doesn't have much effect but it
> > might reduce allocation holes.  Also whatever the value is the limit
> > has to be half the block allocation size for alignment to work
> > properly since the base allocations are assumed to be unaligned.
> >
> > It's also testing against the bytesAlignment aligned size which is not
> > the value bytesAlignment applies to, but by having MAX_ALLOC_SIZE ==
> > BLOCK_SIZE/2 this also 'magically' tests the unaligned allocation size
> > limit required to guarantee satisfaction of the alignment as well.
> > Seems overly tricksy.  Also not a fan of "this should not be possible"
> > comment & assertion that only /seems/ to be there to check this
> > tricksiness and enforce the internal expected behaviour of trySlice()
> > - which isn't really serving any purpose as a separate function since
> > the 'try' only affects the first invocation and it isn't used elsewhere.
> >
> > This also causes the bug above and seems to indicate the
> > straightforward logic flow of "try-to-fit ELSE IF SMALL
> > allocate-and-slice ELSE allocate-separate" all in a single function
> > would be better - even if it does end up with more holes in certain
> > cases (you win some, you lose some).
> It's true that MAX_ALLOC_SIZE is set to half the block so that we can
> still adjust for unaligned allocations within the allocated block. I'll
> see if the logic can be simplified - at the very minimum, if we want to
> reuse implementation between bounded and unbounded, some of these limits
> (block size, max allocation size) need to be made instance-dependent.
> >
> > As an aside the javadoc doesn't seem mention anywhere that
> > bytesAlignment must be a power of 2.  Neither is it checked for
> > validity, that may be on purpose for performance reasons but the
> > comparable posix_memalign() /aligned_alloc() fail with EINVAL if it
> > isn't and well things can get pretty bizarre if it isn't valid.  It
> > isn't an expensive check,
> >
> > or equivalently (Long.lowestOneBit(i) == i).
> The javadoc could probably be made clearer - but the only way to set
> alignment is "withAlignmentBits", and the javadoc there expects bit
> alignment to be a power of two and >= 8. So I think you can conclude
> that byte alignment must also be a power of two.
> One thing which probably fell through the cracks, is that the alignment
> check does not apply when a layout is created - e.g.
> MemoryLayout.valueLayout(10, ByteOrder.nativeOrder()) succeeds, and sets
> alignment of 10, which is incorrect. Same is true for the recursive
> cases, e.g. when a struct/union/sequence layouts are created. I think
> some extra checks are required here. Also, if we want to allow sub-byte
> sizes (e.g. for describing bitmasks) we need to be able to accept bit
> alignment smaller (but still power of two) than 8, I think.
> Maurizio

More information about the panama-dev mailing list