Lab 07: Project Panama — FFM

Time: 60 minutes | Level: Architect | Docker: docker run -it --rm zchencow/innozverse-java:latest bash


Overview

Project Panama's Foreign Function & Memory (FFM) API replaces JNI with a safe, ergonomic way to call native code and manage off-heap memory. Use MemorySegment, Arena, Linker, and MemoryLayout to call C functions directly from Java 21.


Step 1: FFM API Overview

Project Panama FFM replaces JNI:
  JNI (old):                      FFM (Java 21):
  - Write C header                - No C code needed
  - Compile native library        - Direct downcall via Linker
  - Load with System.loadLibrary  - Arena manages memory lifetime
  - Fragile, error-prone          - Type-safe MemoryLayout
  - Cannot be verified by JVM     - Verified by JVM

Core classes:
  MemorySegment  — a bounded region of memory (on-heap or off-heap)
  Arena          — controls lifetime of off-heap memory segments
  Linker         — creates handles to call native functions
  SymbolLookup   — finds native symbols by name
  MemoryLayout   — describes C struct/array memory layout
  ValueLayout    — describes primitive C type layout

Step 2: Arena and MemorySegment

💡 Arena types: ofConfined() (single-thread), ofShared() (multi-thread), ofAuto() (GC-managed), global() (never freed).


Step 3: Calling strlen via Linker


Step 4: MemoryLayout — C Struct Mapping


Step 5: Full strlen via FFM API (Verified)

📸 Verified Output:


Step 6: Calling qsort via FFM

💡 linker.upcallStub() creates a C function pointer from a Java MethodHandle — this is how callbacks work in FFM.


Step 7: Off-Heap Buffer Pattern


Step 8: Capstone — Complete FFM Demo


Summary

Concept
Class/API
Purpose

Memory segment

MemorySegment

Bounded native/heap memory

Memory lifetime

Arena

Scope-bound allocation

Native call

Linker.downcallHandle()

Java → C function

C callback

Linker.upcallStub()

C → Java function pointer

Struct layout

MemoryLayout.structLayout()

C struct mapping

Value layout

ValueLayout.JAVA_INT etc.

Primitive C types

Field access

MemoryLayout.varHandle()

Type-safe field read/write

Symbol lookup

SymbolLookup

Find native function by name

Last updated