
أنهى اليوم قمة JVM LS الثانية عشرة. كالعادة ، كان حدثًا رائعًا مع عروض فنية على الأجهزة الافتراضية واللغات التي تعمل عليها. كالعادة ، عقدت القمة في سانتا كلارا ، في حرم أوراكل. كالعادة ، هناك عدد أكبر من الأشخاص الذين يرغبون في الوصول إلى هنا أكثر من الأماكن: عدد المشاركين لا يتجاوز 120. كالعادة ، لم يكن هناك تسويق ، فقط مخلفاتها.
هذه القمة هي بالفعل الثالثة بالنسبة لي ، وفي كل مرة أزورها بسرور كبير ، على الرغم من النفاثة الرهيبة. هنا لا يمكنك فقط الاستماع إلى التقارير ، ولكن أيضًا التعرف على أشخاص أفضل من عالم JVM ، والمشاركة في المحادثات غير الرسمية ، وطرح الأسئلة في ورش العمل ، والشعور عمومًا بالاشتراك في إنجازات رائعة.
إذا لم تحضر القمة ، فهذا لا يهم. يتم نشر معظم التقارير على موقع يوتيوب مباشرة بعد القمة تقريبًا. في الواقع أنها متوفرة بالفعل . لتسهيل التنقل ، سوف أصف هنا بإيجاز جميع التقارير وورش العمل التي تمكنت من حضورها.
29 يوليو
لا يتعلق هذا بميزات تجميع المستقبل بلغة Clojure ، كما يعتقد الكثيرون ، ولكن ببساطة عن تطور اللغة ، وتعقيدات إنشاء الشفرة والمشاكل التي يواجهونها. على سبيل المثال ، اتضح أنه من المهم في Clojure إلغاء المتغيرات المحلية بعد الاستخدام الأخير ، لأنه إذا كان رئيس القائمة التي تم إنشاؤها بتسلسل في متغير محلي ، ثم تجاوزه ، قد لا يتم تجميع العقد التي تم تجاوزها بالفعل بواسطة جامع البيانات المهملة ، وقد يتعطل البرنامج مع OutOfMemory . بشكل عام ، يقوم برنامج التحويل البرمجي C2 JIT نفسه بإصدار المتغيرات بعد الاستخدام الأخير ، لكن المعيار لا يضمن ذلك ، ولن يقول مترجم HotSpot.
كان من المثير للاهتمام أيضًا معرفة كيفية تنفيذ الإرسال الديناميكي لاستدعاءات الوظائف. تعلمت أيضًا أنه حتى وقت قريب ، كان Clojure يستهدف JVM 6 وتحول مؤخرًا إلى JVM 8. الآن ينظر مؤلفو الترجمة إلى invokeynamic.
مشروع Loom عبارة عن ألياف خفيفة الوزن لـ Java. منذ عام مضى ، تحدث آلان ورون بالفعل عن هذا المشروع ، وبعد ذلك بدا أن كل شيء يسير على ما يرام وكان على وشك الاستعداد. ومع ذلك ، لم يدخل هذا المشروع جافا رسميًا بعد ولا يزال قيد التطوير في مفترق منفصل من المستودع. بالطبع ، اتضح أنه كان من الضروري تسوية الكثير من التفاصيل.
العديد من واجهات برمجة التطبيقات (APIs) القياسية من ReentrantLock.lock إلى Socket.accept تم تكييفها بالفعل للألياف: إذا تم إجراء مثل هذه الدعوة داخل الألياف ، سيتم حفظ حالة التنفيذ ، سيتم إلغاء تراصف المكدس وسيتم تحرير مؤشر ترابط نظام التشغيل للمهام الأخرى حتى يوقظ الحدث الألياف (على سبيل المثال ، ReentrantLock.unlock). ومع ذلك ، على سبيل المثال ، لا تزال الكتلة القديمة المتزامنة الجيدة لا تعمل ، ويبدو أنه لا يمكن القيام بذلك دون إعادة جدولة كل دعم المزامنة في JVM. لن يعمل فك المكدس الآخر في حالة وجود إطارات أصلية في المكدس بين بداية الألياف ونقطة التوقف. في كلتا هاتين الحالتين ، لا ينفجر شيء ، ولكن الألياف لا تطلق الدفق.
هناك العديد من الأسئلة حول كيفية مقارنة الألياف مع فئة java.lang.Thread القديمة. قبل عام ، كانت هناك فكرة لجعل Fiber فئة فرعية من الخيط. لقد رفضوا ذلك الآن وجعلوه كيانًا مستقلاً ، لأن محاكاة كل دفق منتظم في كل الألياف مكلفة للغاية. في هذه الحالة ، سيعيد Thread.currentThread () داخل الألياف المزيج الذي تم إنشاؤه ، وليس الخيط الحقيقي الذي يتم فيه تنفيذ كل شيء. لكن العقبة سوف تتصرف بشكل جيد (على الرغم من أنها يمكن أن تبطئ المهمة). الفكرة المهمة هي عدم إعطاء دفق الوسائط الفعلي تحت أي ظرف من الظروف الذي تعمل عليه الألياف داخل الألياف. قد يكون ذلك خطيرًا حيث يمكن للألياف الانتقال بسهولة إلى خيط آخر. سوف يستمر الخداع.
من الغريب أن المشاركين في المشروع قد دفعوا بالفعل بعض التغييرات التحضيرية إلى مستودع JDK الرئيسي من أجل تسهيل حياتهم. على سبيل المثال ، في Java 13 ، تمت إعادة كتابة طريقة doPrivileged من الكود الأصلي بالكامل في Java ، مما زاد من الأداء بمقدار 50 مرة. لماذا هذا مشروع تلوح في الأفق؟ والحقيقة هي أن هذه الطريقة بالذات تظهر غالبًا في منتصف المكدس ، وعلى الرغم من أنها كانت أصلية ، فإن الألياف التي تحتوي على هذه المجموعة لم تتوقف. بطريقة أو بأخرى ، يستفيد المشروع بالفعل.
في صفحة المشروع ، يمكنك قراءة الوثائق وتنزيل الشجرة المصدر ، وهناك أيضًا مجموعات ثنائية يمكنك أن تلعبها اليوم. نأمل أن يتم دمج كل شيء في السنوات القادمة.
براين جويتز - ورشة عمل "مشروع العنبر"
بالتوازي مع ذلك ، كانت ورشة عمل تدور حول مشروع Loom ، لكنني ذهبت إلى Amber. ناقشنا هنا بإيجاز أهداف المشروع وأهداف التنفيذ المشترك الرئيسية التي يجري العمل فيها - مطابقة الأنماط ، السجلات والأنواع المختومة . ثم وقع النقاش برمته في مسألة تحديد النطاق الخاصة. تحدثت عن هذا في مؤتمر جوكر العام الماضي ، من حيث المبدأ ، لم يقل أي شيء جديد. حاولت دفع فكرة بأنواع الاتحاد الضمنية مثل if(obj instanceof Integer x || obj instanceof Long x) use(x.longValue())
، لكنني لم أشاهد الحماس.
من جميع النواحي ، مشروع رائع من Google للبحث عن السباقات باستخدام البيانات في شكل قراءة وكتابة نفس الحقل أو عنصر الصفيف غير المتقلب من تدفقات مختلفة دون إعداد علاقة يحدث قبل ذلك. تمت كتابة المشروع في الأصل كوحدة LLVM للرمز الأصلي ، والآن تم تكييفه من أجل HotSpot. هذا مشروع OpenJDK رسمي بقائمته البريدية ومستودعه.
وفقا للمؤلفين ، الشيء الآن يعمل تماما ، يمكنك التجمع واللعب. بالإضافة إلى ذلك ، تجد السباق ليس فقط في كود Java ، ولكن أيضًا في كود المكتبات الأصلية. لا يتم البحث عن الأجناس الموجودة في رمز الجهاز الظاهري نفسه ، لأنه توجد كل بدائل التزامن مكتوبة بطريقتها الخاصة ، ولا يستطيع TSan اكتشافها. وفقا للمؤلفين ، TSan لا يعطي ايجابيات كاذبة.
المشكلة الرئيسية هي الأداء. الآن يتم ترجمة المترجم الشفري فقط لرمز Java ، على التوالي ، يتم تعطيل ترجمة JIT تمامًا ، ويتباطأ المترجم البطيء بالفعل عدة مرات. ولكن إذا كان لديك موارد كافية (لدى Google ، بالطبع ، ما يكفي) ، يمكنك أحيانًا قيادة مجموعات الاختبار الخاصة بك باستخدام TSan. من المخطط أيضًا إضافة أجهزة إلى JIT ، ولكن هذا تدخل أكثر خطورة في JVM.
سأل شخص ما إذا كان تعطيل ترجمة JIT لا يؤثر على النتيجة ، لأن بعض السباقات قد لا تظهر على المترجم الشفهي. لم يستبعد المتحدث هذا الاحتمال ، لكنه قال إنهم وجدوا بالفعل عددًا كبيرًا من السباقات التي ستستغرق وقتًا طويلاً للغاية. لذا كن حذرًا عند تشغيل مشروعك تحت TSan: قد تكتشف الحقيقة غير السارة.
الجميع ينتظر أنواع القيم في جافا ، ولكن لا أحد يعرف متى ستظهر. ومع ذلك ، فإن الحركات خطيرة على نحو متزايد. بالفعل هناك اختبار التجميعات الثنائية مع المعلم L2 الحالي. في الخطط الحالية ، ستأتي سلسلة Valhalla الكاملة على علامة L100 ، لكن المؤلفين ما زالوا متفائلين ويعتقدون أن أكثر من 2 بالمائة قد تم إنجازها.
لذلك ، من وجهة نظر اللغة ، لدينا فئات مع المعدل المضمّن ، والتي تتم معالجتها بطريقة خاصة بواسطة الجهاز الظاهري. يمكن تضمين مثيلات هذه الفئات في كائنات أخرى ، كما أن الصفائف المسطحة التي تحتوي على مثيلات للفئات المضمّنة ممكنة أيضًا. لا يحتوي المثيل على رأس ، مما يعني عدم وجود هوية ، يتم اعتبار رمز التجزئة حسب الحقول ، ==
أيضًا حسب الحقول ، أو محاولة مزامنة أو Object.wait()
في مثل هذه الفئة سوف ترفع IllegalMonitorStateException. الكتابة null
إلى متغير من هذا النوع ، بالطبع ، لن تنجح. ومع ذلك ، فإن المؤلفين يقدمون بديلاً: إذا كنت قد أعلنت عن Point
مضمنة في الفئة ، فبإمكانك أن تعلن عن حقل أو متغير من النوع (مفاجأة مفاجأة!) Point?
، وبعد ذلك سيكون هناك كائن كامل على الكومة (مثل الملاكمة) برأس ، وهوية ، null
احتواء القيمة null
فيها.
تظل الأسئلة المفتوحة الخطيرة هي التخصص في المواد العامة وترحيل الفئات الحالية (على سبيل المثال ، Optional
) إلى فئة مضمنة حتى لا يتم فصل الكود الموجود (نعم ، يكتب الناس null
في متغيرات من النوع Optional
). ومع ذلك ، تلوح في الأفق الصورة ، والفجوة واضحة.
لقد كانت مفاجأة لي أن نفس نيل غيفتر ، مؤلف مشارك لألغاز Java الأصلية ، يعمل الآن في Microsoft على .Net وقت التشغيل. كان من المفاجئ أيضًا رؤية تقرير حول CLR (ما يسمى بوقت تشغيل صافي) على JVM LS. ولكن التعرف على تجربة الزملاء من عوالم أخرى مفيد دائمًا. يتحدث التقرير عن مجموعة متنوعة من المراجع والمؤشرات في CLR ، وتعليمات كود الشفرة المستخدمة لأنواع القيم ، وحول كيفية تقليل الوظائف المعممة المتخصصة بشكل جميل. كان من المثير للاهتمام معرفة أن أحد أهداف أنواع القيم في .Net هو تفاعل مع الكود الأصلي. لهذا السبب ، يتم تحديد موقع الحقول في أنواع القيم بدقة ويمكن إسقاطها على بنية بدون تحويلات. JVM لم يكن لديها مثل هذه المهمة ، وماذا تفعل مع interop الأصلي - انظر أدناه.
مرة أخرى تحديث تقرير العام الماضي . مرة أخرى ، السؤال هو لماذا لم يصدروا أي شيء ، إذا كان كل شيء جيدًا قبل عام.
المتجه عبارة عن مجموعة من عدة أرقام ، والتي يمكن تمثيلها في الأجهزة بسجل متجه واحد مثل zmm0 لـ AVX512. في المتجهات ، يمكنك تحميل البيانات من المصفوفات ، وإجراء عمليات عليها مثل الضرب بالعناصر ، ورميها مرة أخرى. يتم دمج جميع العمليات التي توجد بها تعليمات المعالج بواسطة برنامج التحويل البرمجي JIT في هذه التعليمات. عدد العمليات هو ببساطة ضخمة. إذا كان هناك شيء مفقود ، يتم استخدام تطبيق بطيء بديل. من الناحية المثالية ، لا يتم إنشاء الكائنات الوسيطة المتجهة ؛ ويعمل تحليل الهروب. يتم توجيه جميع خوارزميات الحوسبة القياسية مع اثارة ضجة ، وذلك باستخدام كل قوة المعالج.
لسوء الحظ ، من الصعب على المؤلفين ألا يكون لديهم أي valgalla: تحليل الهروب هش وقد لا يعمل بسهولة. يجب أن تكون هذه المتجهات ببساطة فئات مضمّنة ، ثم تختفي جميع المشكلات. ليس من الواضح ما إذا كان يمكن إصدار واجهة برمجة التطبيقات هذه قبل الإصدار الأول من Valgalla. يبدو أكثر استعدادا. من بين المشاكل التي يطلق عليها صعوبات في دعم الكود. هناك العديد من القطع المتكررة لأحجام مختلفة من السجلات وأنواع مختلفة من البيانات ، لذلك يتم إنشاء معظم التعليمات البرمجية من القوالب ويؤلم الاحتفاظ بها.
الاستخدام هو أيضا الكمال. لا يوجد تحميل زائد للمشغل في Java ، لذا تبدو الرياضيات قبيحة: بدلاً من max(va-vb*42, 0)
يجب عليك كتابة va.lanewise(SUB, vb.lanewise(MUL, 42)).lanewise(MAX, 0)
. سيكون من الرائع الوصول إلى AST lambdas كما هو الحال في C #. بعد ذلك ، سيكون من الممكن إنشاء عملية lambda مخصصة مثل MYOP = binOp((va, vb) -> max(va-vb*42, 0))
واستخدامها.
30 يوليو
اليوم الثاني مرت تحت علم التجميع.
يتحدث أحد موظفي IBM ، وهو عضو في مشروع JVM OpenJ9 ، عن تجربتهم مع تجميع JIT و AOT. هناك دائمًا مشاكل: JIT عبارة عن بدء تشغيل بطيء ، لأنها ترتفع درجة حرارتها ؛ تكاليف وحدة المعالجة المركزية لتجميع. AOT - أداء دون المستوى الأمثل بسبب عدم وجود ملف تعريف (من الممكن أن يكون ملف التعريف ، ولكن بشكل غير تافه وليس دائمًا أثناء التشكيل البرمجي يطابق ملف التعريف عند التنفيذ) ، يكون من الصعب استخدامه أو ربطه بالنظام الأساسي الهدف أو نظام التشغيل أو أداة تجميع مجمعي البيانات المهملة. يمكن حل بعض المشكلات عن طريق الجمع بين الأساليب: بدءً من التعليمات البرمجية المترجمة من AOT ثم الانتهاء من JIT. بديل جيد لكل هذا هو التخزين المؤقت JIT. إذا كان لديك العديد من الأجهزة الافتراضية (مرحبًا ، خدمات microservices) ، فكلها تتحول إلى خدمة منفصلة - برنامج مترجم JIT (نعم ، JITaaS) ، حيث كل شيء يشبه موازنة البالغين ، والتنسيق ، وموازنة الأحمال. هذه الخدمة تجمع. في كثير من الأحيان ، يمكنه إعطاء رمز جاهز لطريقة معينة ، لأن هذه الطريقة قد تم تجميعها بالفعل على JVM آخر. هذا يحسن الاحماء بشكل كبير ، ويزيل استهلاك الموارد من خدمة JVM ، ويقلل عمومًا من إجمالي استهلاك الموارد.
بشكل عام ، يمكن أن تكون JITaaS الكلمة الطنانة التالية في عالم JVM. لسوء الحظ ، لم أتمكن من معرفة ما إذا كان يمكن تشغيل هذا الأمر الآن أم أنه لا يزال تطورًا مغلقًا.
GraalVM Native Image هو تطبيق Java تم تجميعه في تعليمة برمجية أصلية تعمل بدون JVM (على عكس الوحدات النمطية المترجمة باستخدام برنامج التحويل البرمجي AOT مثل jaotc). بتعبير أدق ، هذا ليس تطبيق جافا. لكي يعمل بشكل صحيح ، يحتاج إلى عالم مغلق ، أي أنه يجب أن تكون جميع التعليمات البرمجية مرئية في مرحلة الترجمة ، بدون Class.forName. يمكنك التعامل مع الانعكاسات والأسلوب ، ولكن عندما تقوم بالتجميع ، عليك أن تحدد على وجه التحديد الفئات والطرق التي سيتم استخدامها من خلال الانعكاس.
شيء ممتع آخر هو تهيئة الصف. تتم تهيئة العديد من الفئات أثناء التجميع. بمعنى ، سيتم حساب الحقول الثابتة الخاصة بك افتراضيًا بواسطة المترجم وسيتم كتابة النتيجة على الصورة المجمعة ، وعند بدء تشغيل التطبيق ، تتم قراءتها ببساطة. هذا مطلوب من أجل تحقيق جودة ترجمة أفضل: يمكن إجراء أي طي ثابت إذا كانت قيم الحقول الثابتة معروفة للمترجم. كل شيء على ما يرام مع JIT ، المترجم ينفذ التهيئة الثابتة ، ومن ثم معرفة الثوابت ، يمكنك ترجمة. وعند بناء تطبيق أصلي ، عليك أن تخدعك. هذا ، بطبيعة الحال ، يؤدي إلى متعة آثار مخدر. لذلك عادة ما تتم تهيئة الفئات بالترتيب الذي يتم الوصول إليه به ، وخلال عملية الترجمة هذا الترتيب غير معروف والتهيئة في أخرى ممكنة. إذا كانت هناك مراجع دائرية بين مُهيئات الفصل ، يمكنك أن ترى الفرق في سلوك كود JVM وفي الصورة الأصلية.
ورشة شاتزل - هوت سبوت جي سي.
فرز جميع الآلام المرتبطة جامعي القمامة. لسوء الحظ ، لقد استمعت إلى أكثر من غيرها. أتذكر أنه تمت مناقشة استدعاء ذاكرة نظام التشغيل ، بما في ذلك Xmx مثيرة للاشمئزاز للجميع. هناك أخبار سارة: في Java 13 ، يتم إضافة خيار جديد - XXX: SoftMaxHeapSize. حتى الآن ، يتم دعمه فقط من قبل جامع ZGC ، ولكن G1 يمكنه أيضًا اللحاق بالركب. يضع حدًا لحجم الكومة ، التي يجب ألا يتم تجاوزها إلا في حالات الطوارئ ، عندما لا تعمل بشكل مختلف. وبالتالي ، يمكنك تعيين Xmx كبيرة (على سبيل المثال ، مساوية لحجم RAM بالكامل) وبعض SoftMaxHeapSize معقول. بعد ذلك ، ستحتفظ JVM بنفسها خلال معظم الوقت ، لكن في وقت الذروة ، لن يتم التخلص من OutOfMemoryError ، ولكنها ستأخذ ذاكرة أكبر من نظام التشغيل. عندما ينخفض الحمل ، ستعود الذاكرة.
تحدث Microsoft Mei-Chin Tsai عن ميزات تجميع JIT و AOT في CLR. تم تطوير AOT compilation لهم منذ فترة طويلة ، ولكن في البداية (ngen.exe) تم تنفيذه على النظام الأساسي الهدف ، يشبه إلى حد ما أول مرة يتم تشغيله (إذا كان لديك Windows ، فابحث عن ملفات * .ni.dll في مجلد Windows). يتم الحصول على الملفات اعتمادا على إصدار ويندوز المحلية وحتى على غيرها من DLL- ek. وفقًا لذلك ، إذا تم تحديث التبعية ، فيجب إعادة تجميع جميع الوحدات الأصلية. في الجيل الثاني (crossgen) ، قام المؤلفون مسبقًا بتجميع التطبيقات والوحدات المستقلة نسبياً عن إصدارات الأجهزة ونظام التشغيل والتبعيات. تباطأ هذا الرمز لأن مكالمات التبعية يجب أن تتم الآن بأمانة. تم حل هذه المشكلة عن طريق توصيل JIT وإعادة ترجمة الكود الساخن أثناء التطبيق. ثم تحدثنا عن التجميع متعدد المستويات (المتدرج) (يبدو أن هذا في CLR في مراحله الأولى ، بينما كان يتطور في Java لمدة عشر سنوات على الأقل) وحول الخطط المستقبلية لجعل AOT مشتركة بالفعل.
قدم زملاء علي بابا نهجهم لمشكلة الاحماء JVM. يستخدمون JVM للعديد من خدمات الويب. من حيث المبدأ ، فإن بدء التشغيل السريع للغاية ليس مهمًا للغاية ، لأن الموازن يمكنه دائمًا الانتظار حتى يتم رفع الماكينة والبدء في إرسال الطلبات إليها فقط. ومع ذلك ، فإن المشكلة تكمن في أن الجهاز لا يتم تسخينه بدون طلبات: لا يتم استدعاء الكود الذي يصف منطق معالجة الطلبات ، مما يعني أنه لا يتم تجميعه. سيتم تجميعها عند وصول الطلبات الأولى ، أي بغض النظر عن مقدار انتظار الموازن ، سيكون هناك فشل في أداء الطلبات الأولى. في السابق ، حاولوا حل هذا عن طريق طرح طلبات وهمية على الخدمة القادمة قبل إرسال طلبات حقيقية إليها. هذا الأسلوب مثير للاهتمام ، ولكن من الصعب جدًا إنشاء مثل هذا الدفق المزيف الذي قد يتسبب في تجميع كل الشفرة الضرورية.
مشكلة منفصلة هي deoptimization. في أول ألف استفسار ، واحد if
دائمًا يتماشى مع الفرع الأول ، قام مترجم JIT عمومًا بإلقاء الثاني ، بإدخال فخ deoptimization هناك لتقليل حجم الرمز. لكن الطلب رقم 1001 ذهب إلى الفرع الثاني ، وعملت عملية إزالة الأوساط ، وذهب الأسلوب بأكمله إلى المترجم الشفهي. بينما يتم تجميع الإحصائيات مرة أخرى ، بينما يتم ترجمة الأسلوب بواسطة برنامج التحويل البرمجي C1 ، ثم بواسطة ملف التعريف الكامل بواسطة برنامج التحويل البرمجي C2 ، سيواجه المستخدمون تباطؤًا. وبعد ذلك بنفس الطريقة ، if
بالإمكان إبطال مفعولها ، وسيستمر كل شيء بطريقة جديدة.
JWarmUp يحل المشكلة على النحو التالي. أثناء التشغيل الأول للخدمة ، يتم كتابة سجل تجميع لعدة دقائق: فهو يسجل الأساليب التي تم تجميعها ومعلومات ملفات التعريف الضرورية حسب الفروع والأنواع ، وما إلى ذلك. في حالة إعادة تشغيل هذه الخدمة ، مباشرة بعد بدء التشغيل ، تتم تهيئة جميع الفئات من السجل ويتم تجميع الأساليب المسجلة مع الأخذ بعين الاعتبار الملف الشخصي السابق. نتيجة لذلك ، سيعمل المترجم بشكل جيد عند بدء التشغيل ، وبعد ذلك سيبدأ الموازن في إرسال الطلبات إلى JVM. بحلول هذا الوقت ، تم تجميع جميع الشفرات الساخنة التي تم تجميعها بالفعل.
تجدر الإشارة إلى أن مشكلة البداية السريعة لم يتم حلها هنا. يمكن أن يكون الإطلاق أبطأ لأن العديد من الطرق يتم تجميعها ، وقد يكون بعضها مطلوبًا بعد دقائق فقط من الإطلاق. لكن تبين أن السجل قابل لإعادة الاستخدام: بخلاف AOT ، يمكنك رفع الخدمة على بنية مختلفة أو باستخدام أداة تجميع مجمعي بيانات غير مختلفة وإعادة استخدام السجل السابق.
يحاول المؤلفون منذ فترة طويلة دفع JWarmUp إلى OpenJDK. حتى الآن دون جدوى ، ولكن العمل يتحرك. الشيء الرئيسي هو أن التصحيح الكامل يمكن الوصول إليه تمامًا على خادم Code Review ، بحيث يمكنك تطبيقه بسهولة على مصادر HotSpot وإنشاء JVM بنفسك باستخدام JWarmUp.
هذه ورقة بحثية من مانشستر ، لكن المؤلفين يدعون أن المشروع قد تم تنفيذه بالفعل في بعض الأماكن. إنها أيضًا وظيفة إضافية لـ OpenJDK ، مما يجعل من السهل جدًا نقل تعليمات برمجية معينة إلى Java إلى GPU أو iGPU أو FPGA أو ببساطة موازنتها إلى قلب معالجها. للتجميع على وحدة معالجة الرسومات ، يستخدمون GraalVM حيث بنوا الخلفية الخاصة بهم - TornadoJIT. تنتقل طريقة Java المكتوبة بشكل صحيح بشفافية إلى الجهاز المقابل. صحيح ، يقولون إن التجميع على FPGA قد يستغرق عدة ساعات ، ولكن إذا تم اعتبار مهمتك شهرًا ، فلماذا لا. بعض المعايير (على سبيل المثال ، تحويل فورييه المنفصل) هي أكثر من مائة مرة أسرع من جافا العارية ، والتي من المتوقع من حيث المبدأ. تم تحميل المشروع بالكامل إلى جيثب ، حيث يمكنك أيضًا العثور على المنشورات العلمية حول هذا الموضوع.
كل نفس الأغنية - مشروع طويل الأمد ، كل عرض تقديمي للقمة ، قبل عام بدا كل شيء جاهزًا ، لكن لم يصدر أي إصدار بعد. اتضح أنه منذ ذلك الحين تحول التركيز.
فكرة المشروع هي تداخل محسّن مع الكود الأصلي. يعلم الجميع كم هو مؤلم استخدام JNI. انه لامر مؤلم حقا. يبطل مشروع بنما هذا الألم: استخدام فصول jextract Java يتم إنشاؤها من ملفات * .h الخاصة بالمكتبة الأصلية ، والتي تعتبر ملائمة تمامًا للاستخدام عن طريق استدعاء الأساليب المحلية. على جانب C / C ++ ، لا يلزمك كتابة سطر واحد على الإطلاق. بالإضافة إلى ذلك ، أصبح كل شيء أسرع بكثير: الحمل على المكالمات إلى Java-> الأصلي والوطني-> سقط Java في بعض الأحيان. أكثر ما يمكن أن تريد؟
هناك مشكلة موجودة منذ بعض الوقت - نقل صفائف البيانات إلى رمز أصلي. حتى الآن ، فإن الطريقة الموصى بها هي DirectByteBuffer ، والتي لديها الكثير من المشاكل. أحد الأخطر هو عمر غير مدار (سيختفي المخزن المؤقت عندما يلتقط جامع البيانات المهملة كائن Java المناسب). بسبب هذا والمشاكل الأخرى ، يستخدم الناس خدمة غير آمنة ، والتي ، مع بذل العناية الواجبة ، يمكن أن تضع الجهاز الظاهري بأكمله بسهولة.
هذا يعني أنك بحاجة إلى وصول جديد للذاكرة العادية خارج كومة Java. التخصيص ، المساعدون المنظمون ، الإزالة الصريحة. أدوات الوصول الهيكلية - بحيث لا تضطر إلى حساب الإزاحات بنفسك إذا كنت بحاجة إلى الكتابة ، على سبيل المثال ، struct { byte x; int y; }[5]
struct { byte x; int y; }[5]
struct { byte x; int y; }[5]
. بدلاً من ذلك ، يمكنك وصف تخطيط هذه البنية مرة واحدة ثم القيام بذلك ، على سبيل المثال ، VarHandle
، والذي يمكنه قراءة كل x
بالقفز فوق y
. في هذه الحالة ، بالطبع ، يجب أن يكون هناك دائمًا فحص الحدود ، كما في مصفوفة جافا العادية. بالإضافة إلى ذلك ، يجب أن يكون هناك حظر على الوصول إلى منطقة مغلقة بالفعل. ويتبين أن هذه مهمة غير تافهة إذا أردنا الحفاظ على الأداء بمستوى غير آمن والسماح بالوصول من عدة سلاسل رسائل. باختصار ، شاهد الفيديو ، ممتع للغاية.
ورشة عمل: فلاديمير كوزلوف - مشروع متروبوليس
يجمع مشروع متروبوليس بين كل المحاولات لإعادة كتابة أجزاء من JVM في جاوة. الجزء الرئيسي اليوم هو المترجم Graal. في السنوات الأخيرة ، تطورت بشكل جيد وهناك بالفعل حديث حقيقي عن بديل كامل للشيخوخة C2. كانت هناك مشكلة في التمهيد: بدأت الكأس ببطء ، لأنه كان لابد من تجميع أو تفسير JIT. ثم ظهرت مجموعة AOT (نعم ، الهدف الرئيسي لمشروع تجميع AOT هو التمهيد للكأس نفسها). ولكن مع AOT ، فإن الكأس تلتهم جزءًا لائقًا من كومة تطبيق Java التي قد لا ترغب في مشاركة كومة الذاكرة المؤقتة الخاصة بها. لقد تعلمنا الآن تحويل الكأس إلى مكتبة أصلية باستخدام Graal Native Image ، مما سمح لنا في النهاية بعزل المترجم عن الكومة العامة. مع أعلى أداء للرمز الذي جمعته الكأس ، لا تزال هناك مشاكل في بعض المعايير. على سبيل المثال ، يتأخر الكأس وراء C2 في الجوهرية والتوجه. ومع ذلك ، فبفضل التحليل القوي للغاية للهروب والهروب ، يكسر ببساطة C2 على الكود الوظيفي ، حيث يتم إنشاء العديد من الكائنات الثابتة والعديد من الوظائف الصغيرة. إذا كنت تكتب على الصخرة وما زلت لا تستخدم الكأس ، فركض لاستخدامها. علاوة على ذلك ، في أحدث إصدارات JDK ، من السهل جدًا القيام ببعض المفاتيح ، كل شيء موجود بالفعل في المجموعة.
31 يوليو
كيفن بورليون - شروح لاغية لجافا
أعلن كيفن عن مشروع جديد ، لكنه طلب عدم التحدث علناً وعدم نشر تسجيل لخطابه على YouTube. اسف جدا , .
Sorbet (!) Ruby, Ruby . , Stripe Ruby , , . , .
Lightning Talks
- . Remi Forax , , . , :
, - , .
ML AI , . , Facebook — getafix , --, , . . , , . , , .
. . OpenJDK Committer Workshop.