"Malloc/Free" Callbacks for Dynamic Off-heap MemorySegments
leerho
leerho at gmail.com
Sun Apr 18 19:03:14 UTC 2021
Maurizo,
Thank you for your detailed reply!
I am trying to grok the full implications of the new concepts in 17
including SegmentAllocator, the concept of arenas as well as
ResourceScope. So this response may not be fully coherent :)
To answer your initial questions:
>
> The possibility of "growing" an existing memory segment (e.g.
> <Unsafe>.reallocate()) ? --- Absolutely not.
The ability to hook in a custom allocator? Yes.
The snippet you wrote certainly answers part of the scenario -- the ability
to intercept *close via *scope.
In my (ideal) model, a child process would be constructed with an initial
segment: *new Child(MemorySegment) *as part of a constrained arena. And
there could be millions of them.
The child consumes use of its allocated segment as a consequence of its
update(...) method. Only the child knows when its segment is full and
needs more memory, at which point it requests a new larger segment. When it
receives a new larger segment, the child has the responsibility of moving
its data over to the new segment and requesting *oldSeg.scope().close(), *which
is intercepted by the Tracking Allocator.
In order for your proposal to work with *allocate*, the Child would have to
be constructed with *new Child(TrackingAllocator, MemorySegment) *in order
for it to access* allocate. *This is certainly possible, however, what
would be nice (and symmetric) would be for the child to be able to access
*allocate* via the scope as well. Sort of a *scope.addOnAllocate(Runnable)
*or perhaps a *scope*.*addOnTrackingAllocator(interface) *that could handle
both*., *But I can see that this is more complex and may not be practical.
Lee.
On Fri, Apr 16, 2021 at 4:27 AM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:
>
> On 16/04/2021 11:55, Maurizio Cimadamore wrote:
> > The answer to the former is "yes!" (and we do so via the
> > SegmentAllocator interface in the new API, which accepted anywhere a
> > segment needs to be allocated).
>
> To be clear, this is what I had in mind, which might, or might not be
> what you were alluding to:
>
> ```
> public class TestAllocator {
> public static void main(String[] args) {
> TrackingAllocator trackingAllocator = new TrackingAllocator();
> MemorySegment segment =
> trackingAllocator.allocate(MemoryLayouts.JAVA_DOUBLE);
> segment.scope().close();
> }
>
> static class TrackingAllocator implements SegmentAllocator {
> @Override
> public MemorySegment allocate(long bytesSize, long
> bytesAlignment) {
> ResourceScope scope = ResourceScope.newConfinedScope();
> MemorySegment segment =
> MemorySegment.allocateNative(bytesSize, bytesAlignment, scope);
> onAllocate(segment);
> scope.addOnClose(() -> onClose(segment));
> return segment;
> }
>
> void onAllocate(MemorySegment segment) {
> System.out.println("Allocated - " + segment);
> }
>
> void onClose(MemorySegment segment) {
> System.out.println("Freed - " + segment);
> }
> }
> }
> ```
>
> This prints, when executed:
>
> ```
> Allocated - MemorySegment{ id=0x1ee42522 limit: 8 }
> Freed - MemorySegment{ id=0x1ee42522 limit: 8 }
> ```
>
> I'm sure this is overly simplistic, but it should illustrate a possible
> approach to do tackle the issues you describe?
>
> Maurizio
>
>
More information about the panama-dev
mailing list