خداحافظ jni: پذیرش عملکرد و حافظه خارجی جاوا

خداحافظ jni ، سلام ffm api
API عملکرد و حافظه خارجی (FFM) جایگزینی مدرن و ظریف برای JEP های قدیمی تر است-یعنی JEP 393 (API دسترسی به حافظه خارجی) و JEP 389 (API پیوند دهنده خارجی)-از این رو به عنوان ویژگی های جوجه کشی در JDK 16 معرفی شده است. مأموریت آن؟ برای ساختن روزهای دردناک رابط بومی جاوا (JNI) به یک خاطره دور.
JNI ، در حالی که از نظر تاریخی برای پل زدن جاوا و کد بومی (به طور معمول C یا C ++) ضروری است ، کاستی های اساسی دارد:
- امضاهای روش بومی و شکننده و شکننده
- مدیریت حافظه دشوار و ناامن
- محدودیت های حافظه تنگ (2 گیگابایت ~)
- عملکرد ضعیف به دلیل باتلاق پیچیده
یک مثال سنتی JNI به ابزارهای خارجی مانند نیاز دارد javah
، مراحل تدوین بومی و پرونده های هدر خسته کننده. همه اینها فقط برای تعامل با یک عملکرد بومی است.
حافظه ، متفاوت مدیریت می شود: API حافظه خارجی
وارد کردن API حافظه خارجی، که اجازه می دهد تا تعامل حافظه خاموش-در جاوا خالص-با ایمنی داخلی و عملکرد بالا.
در هسته آن است MemorySegment
رابط این یک بلوک حافظه را نشان می دهد و تضمین می کند:
- بررسی مرزها
- پیشگیری از اشکالات بدون استفاده
- حفاظت برای الگوهای دسترسی مداوم
کنترل چرخه عمر با عرصه ها
برای رسیدگی به طول عمر تخصیص حافظه ، API FFM معرفی می کند عرصه، انتزاع قدرتمندی برای مدیریت حافظه. چهار نوع عرصه انعطاف پذیری را ارائه می دهند:
- جهانی: هرگز آزاد نشده ، برای ثابت ها مفید است
- خودرو: حافظه توسط GC آزاد می شود
- محدود: Lifetime محدود به یک دامنه (بدون منابع)
- مشترک: حافظه ایمن نخ با پاکسازی صریح
JEP 312 (دستهای محلی و محلی) با ارائه کنترل پاکسازی حافظه ریز دانه در میان موضوعات ، عرصه های مشترک را تکمیل می کند.
خواندن و نوشتن حافظه: الف Rectangle
نمونه
فرض کنید ما می خواهیم این ساختار C بومی را در جاوا نقشه برداری کنیم:
struct Rectangle {
int width;
int height;
};
با FFM در جاوا ، می توانید مانند این با آن تخصیص داده و با آن ارتباط برقرار کنید:
MemoryLayout RECTANGLE = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName("width"),
ValueLayout.JAVA_INT.withName("height")
);
static final VarHandle WIDTH_H = RECTANGLE.varHandle(PathElement.groupElement("width"));
static final VarHandle HEIGHT_H = RECTANGLE.varHandle(PathElement.groupElement("height"));
try (Arena arena = Arena.ofConfined()) {
MemorySegment rect = arena.allocate(RECTANGLE);
WIDTH_H.set(rect, 0L, 40);
HEIGHT_H.set(rect, 0L, 60);
int width = (int) WIDTH_H.get(rect, 0L);
int height = (int) HEIGHT_H.get(rect, 0L);
System.out.println("Area: " + (width * height)); // Output: Area: 2400
}
این رویکرد از ریاضیات جبران دستی جلوگیری می کند و به شما امکان دسترسی به حافظه بومی را با ایمنی از نوع کامل و بررسی های زمان اجرا می دهد.
خداحافظ دیگ بخار: ملاقات کنید jextract
برای تماس با توابع بومی ، API عملکرد خارجی (بخشی از FFM) در کنار یک ابزار قدرتمند کار می کند: jextract
بشر این اتصال جاوا از هدر C به طور خودکار ایجاد می کند.
مثال: تماس با C abs
عملکرد از stdlib.h
:
jextract --output classes --target-package org.cstdlib /usr/include/stdlib.h
سپس ، در جاوا:
import org.cstdlib.stdlib;
try (Arena arena = Arena.ofConfined()) {
int result = stdlib.abs(-42);
System.out.println(result); // Output: 42
}
بدون کد چسب JNI. هیچ سردرد تالیف بومی وجود ندارد. فقط جاوا خالص ، صحبت با کد بومی.
خلاصه
FFM API نفس هوای تازه ای برای توسعه دهندگان است که با JNI کشتی گرفته اند. با مدیریت حافظه ایمن تر ، بین المللی بومی پاک کننده و ابزارهایی مانند jextract
، جاوا اکنون حتی در کارهای برنامه نویسی سیستم های سطح پایین احساس می کند.
این که آیا شما به ساختارهای بومی اختصاص می دهید ، به کتابخانه های C یا مدیریت بافرهای خارج از خانه ، FFM قدرت بومی را به جاوا می رساند-بدون قربانی کردن خوانایی یا ایمنی.