"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