الاختلافات الحقيقية بين "java -server" و "java -client"؟

StackOverflow https://stackoverflow.com/questions/198577

  •  10-07-2019
  •  | 
  •  

سؤال

هل هناك أي فرق عملي حقيقي بين "java -server" و"java -client"؟

كل ما يمكنني العثور عليه على موقع صن غامض

"-يبدأ الخادم بشكل أبطأ ولكن يجب أن يعمل بشكل أسرع".

ما هي الاختلافات الحقيقية؟(باستخدام JDK 1.6.0_07 حاليًا.)

هل كانت مفيدة؟

المحلول

ويرتبط هذا حقا ل نقطة اتصال والافتراضي قيم الخيار (خيارات Java HotSpot VM) والتي تختلف بين تكوين العميل والخادم.

من الفصل 2 من الورقة البيضاء (بنية محرك أداء Java HotSpot):

يشتمل JDK على نوعين من VM - عرض من جانب العميل، وVM مضبوط لتطبيقات الخادم.يشترك هذان الحلان في قاعدة التعليمات البرمجية لبيئة تشغيل Java HotSpot، لكنهما يستخدمان مترجمين مختلفين يتناسبان مع خصائص الأداء الفريدة المميزة للعملاء والخوادم.تتضمن هذه الاختلافات سياسة الترجمة المضمنة وافتراضيات الكومة.

على الرغم من أن الخادم VMs والعميل متشابهان، فقد تم ضبط Server VM خصيصًا لتحقيق أقصى سرعة تشغيل.إنه مخصص لتنفيذ تطبيقات الخادم طويلة الأمد، والتي تحتاج إلى أسرع سرعة تشغيل ممكنة أكثر من وقت بدء سريع أو مساحة ذاكرة أصغر في وقت التشغيل.

يعمل برنامج التحويل البرمجي Client VM كترقية لكل من Classic VM والمترجمين في الوقت المناسب (JIT) الذي تستخدمه الإصدارات السابقة من JDK.يوفر Client VM أداءً محسنًا لوقت التشغيل للتطبيقات والتطبيقات الصغيرة.تم ضبط Java HotSpot Client VM خصيصًا لتقليل وقت بدء تشغيل التطبيق ومساحة الذاكرة، مما يجعله مناسبًا بشكل خاص لبيئات العملاء.بشكل عام، نظام العميل أفضل بالنسبة لواجهات المستخدم الرسومية.

وبالتالي فإن الفرق الحقيقي موجود أيضًا على مستوى المترجم:

لا يحاول برنامج التحويل البرمجي Client VM تنفيذ العديد من التحسينات الأكثر تعقيدًا التي يقوم بها المحول البرمجي في Server VM، ولكن في المقابل، يتطلب وقتًا أقل لتحليل وتجميع جزء من التعليمات البرمجية.وهذا يعني أن جهاز Client VM يمكن أن يبدأ التشغيل بشكل أسرع ويتطلب مساحة أصغر للذاكرة.

يحتوي Server VM على مترجم تكيفي متقدم يدعم العديد من نفس أنواع التحسينات التي يتم إجراؤها عن طريق تحسين برامج التحويل البرمجي C++، بالإضافة إلى بعض التحسينات التي لا يمكن إجراؤها بواسطة برامج التحويل البرمجي التقليدية، مثل التضمين القوي عبر استدعاءات الطريقة الافتراضية.هذه ميزة تنافسية وأداء على المترجمين الثابتين.تتميز تقنية التحسين التكيفي بالمرونة الشديدة في نهجها، وعادةً ما تتفوق في الأداء حتى على تقنيات التحليل والتجميع الثابتة المتقدمة.

ملحوظة:الافراج عن تحديث Jdk6 10 (يرى تحديث ملاحظات الإصدار: التغييرات في 1.6.0_10) حاول تحسين وقت بدء التشغيل، ولكن لسبب مختلف عن خيارات نقطة الاتصال، حيث يتم تعبئته بشكل مختلف باستخدام نواة أصغر بكثير.


ز.ديميكي يشير الى في التعليقات أنه في إصدارات 64 بت من JDK، فإن -client يتم تجاهل الخيار لسنوات عديدة.
يرى شبابيك java يأمر:

-client

يحدد Java HotSpot Client VM.
يتجاهل JDK القادر على تشغيل 64 بت حاليًا هذا الخيار ويستخدم بدلاً من ذلك Java Hotspot Server VM.

نصائح أخرى

والفرق الفوري الأكثر وضوحا في الإصدارات القديمة من جافا سيكون الذاكرة المخصصة ل-client بدلا من تطبيق -server. على سبيل المثال، على بلدي نظام لينكس، وأحصل على:

$ java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 66328448         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 1063256064       {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 16777216         {pd product}
java version "1.6.0_24"

وكما أنه تخلف عن -server، ولكن مع خيار -client أحصل على:

$ java -client -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 16777216         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 268435456        {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 12582912         {pd product}
java version "1.6.0_24"

وحتى مع -server معظم حدود الذاكرة والمخصصات الأولية هي أعلى من ذلك بكثير لهذا الإصدار java.

وهذه القيم يمكن أن تتغير لمجموعات مختلفة من الهندسة المعمارية وأنظمة التشغيل والإصدارات JVM ولكن. الإصدارات الأخيرة من JVM وإزالة الأعلام وأزال الكثير من الفروق بين الخادم والعميل.

وتذكر أيضا أنه يمكنك مشاهدة كافة التفاصيل من jvm تشغيل باستخدام jvisualvm. وهذا مفيد إذا كان لديك المستخدمين الذين أو وحدات التي وضعت JAVA_OPTS أو استخدام البرامج النصية التي تغير خيارات سطر الأوامر. هذا وسوف تسمح لك أيضا مراقبة، في الوقت الحقيقي، <م> كومة و <م> permgen استخدام الفضاء جنبا إلى جنب مع الكثير من احصائيات الأخرى.

واحد الفرق لقد لاحظت فقط هو أنه في وضع "العميل"، يبدو أن JVM في الواقع يعطي بعض الذاكرة غير المستخدمة إلى نظام التشغيل، في حين مع وضع "الخادم"، وبمجرد أن JVM الاستيلاء على الذاكرة، وفاز " ر يعيدها. الذي كيف يبدو على سولاريس مع Java6 على أي حال (باستخدام prstat -Z لمعرفة مقدار الذاكرة المخصصة للعملية).

أنظمة العميل والخادم هي ثنائيات مختلفة.إنهما في الأساس مترجمان مختلفان (JITs) يتفاعلان مع نفس نظام وقت التشغيل.يعد نظام العميل مثاليًا للتطبيقات التي تحتاج إلى أوقات بدء تشغيل سريعة أو آثار أقدام صغيرة، ويعتبر نظام الخادم مثاليًا للتطبيقات التي يكون فيها الأداء العام هو الأكثر أهمية.بشكل عام، يعد نظام العميل أكثر ملاءمة للتطبيقات التفاعلية مثل واجهات المستخدم الرسومية

enter image description here

نقوم بتشغيل الكود التالي مع كلا المفتاحين:

package com.blogspot.sdoulger;

public class LoopTest {
    public LoopTest() {
        super();
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        spendTime();
        long end = System.currentTimeMillis();
        System.out.println("Time spent: "+ (end-start));

        LoopTest loopTest = new LoopTest();
    }

    private static void spendTime() {
        for (int i =500000000;i>0;i--) {
        }
    }
}

ملحوظة: تم تجميع الكود مرة واحدة فقط!الفصول هي نفسها في كلا السباقين!

مع -العميل:
java.exe -client -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
قضاء الوقت:766

مع -الخادم:
java.exe -server -classpath C:\mywork\classes com.blogspot.sdoulger.LoopTest
قضاء الوقت:0

يبدو أنه كلما كان التحسين الأكثر عدوانية لنظام الخادم، قم بإزالة الحلقة لأنه يفهم أنها لا تقوم بأي إجراء!

مرجع

وتوفر وثائق Oracle على الإنترنت بعض المعلومات عن جافا SE 7.

في جافا - تطبيق قاذفة الصفحة جافا ويندوز ، يتم تجاهل الخيار -client في JDK 64 بت:

<اقتباس فقرة>   

وحدد جاوة بؤرة عميل VM. يتجاهل وجدك قادر 64 بت في هذا الخيار وبدلا من ذلك يستخدم جافا بؤرة خادم VM.

ولكن (لجعل الامور مثيرة للاهتمام)، تحت -server ذلك ما يلي:

<اقتباس فقرة>   

وحدد جافا بؤرة خادم VM. على جدك قادرة 64 بت معتمد فقط جافا بؤرة خادم VM ذلك الخيار -Server ضمنيا. هذا هو عرضة للتغيير في إصدار مستقبلي.

ووhref="http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html"> خادم الفئة- الصفحة كشف آلة

وأنا لا أعرف كم من هذه ينطبق على JDK 6.

من جويتز - تزامن جافا في الممارسة العملية:

  1. نصيحة التصحيح:بالنسبة لتطبيقات الخادم، تأكد دائمًا من تحديد -server تبديل سطر أوامر JVM عند استدعاء JVM، حتى للتنمية والاختبار.يقوم الخادم JVM بتحسين أكثر من العميل JVM ، مثل رفع المتغيرات من حلقة لم يتم تعديلها في الحلقة ؛الكود الذي قد يبدو أنه يعمل في بيئة التطوير (Client JVM) يمكن أن يكسر بيئة النشر (Server JVM).على سبيل المثال ، لو نسينا أن نعلن أن المتغير نائم على أنه متقلب في القائمة 3.4 ، يمكن أن يرفع الخادم JVM الاختبار من الحلقة (يحولها إلى حلقة لا حصر لها) ، لكن العميل JVM لن يفعل ذلك.حلقة لا حصر لها تظهر في التطوير أقل تكلفة بكثير من تلك التي تظهر فقط في الإنتاج.

القائمة 3.4.عد الخراف.

volatile boolean asleep; ... while (!asleep) countSomeSheep();

التركيز بلدي.YMMV

وIIRC، كان ينطوي على استراتيجيات جمع القمامة. نظرية هي أن العميل والخادم سوف تكون مختلفة من حيث الأشياء لم تدم طويلا، وهو أمر مهم لخوارزميات GC الحديثة.

هنا هو وجود صلة على وضع ملقم. للأسف، فإنها لا تذكر وضع العميل.

هنا هو وجود صلة دقيق جدا في GC بشكل عام. هذا هو المادة أكثر أساسية . لست متأكدا إذا كان أي عنوان -Server مقابل -client ولكن هذا هو المواد ذات الصلة.

وفي لا الزغب فقط الاشياء، سواء كين SIPE وجلين Vandenburg القيام محادثات كبيرة على هذا النوع من الشيء.

ولقد لاحظت أي فرق في وقت بدء التشغيل بين 2، ولكن سجلت تحسنا ضئيلا للغاية في أداء التطبيقات مع "-Server" (خادم سولاريس، الجميع يستخدمون أشعة الشمس لتشغيل التطبيق). وكان ذلك تحت 1.5.

آخر مرة ألقيت نظرة على هذا، (ومن المسلم به أنه كان منذ فترة من الوقت) كان الفرق الأكبر الذي لاحظته هو في جمع القمامة.

IIRC:

  • يحتوي VM كومة الخادم على عدد مختلف من الأجيال عن Client VM، وخوارزمية مختلفة لجمع البيانات المهملة. قد لا يكون هذا صحيحا بعد الآن
  • سيقوم الخادم VM بتخصيص الذاكرة وعدم تحريرها لنظام التشغيل
  • سيستخدم جهاز VM الخاص بالخادم خوارزميات تحسين أكثر تعقيدًا، وبالتالي يتطلب وقتًا أكبر ومتطلبات ذاكرة أكبر للتحسين

إذا كان بإمكانك مقارنة جهازي Java VMs وعميل واحد وخادم واحد باستخدام jvisualvm الأداة، يجب أن ترى اختلافًا في تكرار وتأثير جمع البيانات المهملة، وكذلك في عدد الأجيال.

كان لدي زوج من لقطات الشاشة التي أظهرت الفرق جيدًا، لكن لا يمكنني إعادة إنتاجه لأن لدي JVM 64 بت والذي ينفذ فقط VM للخادم.(ولا يمكنني أن أزعج نفسي بتنزيل الإصدار 32 بت والنقاش فيه على نظامي أيضًا.)

لا يبدو أن هذا هو الحال بعد الآن، بعد أن حاولت تشغيل بعض التعليمات البرمجية على النوافذ مع كل من الأجهزة الافتراضية للخادم والعميل، يبدو أنني حصلت على نفس نموذج الجيل لكليهما ...

عند القيام الهجرة 1،4-1،7 ( "1.7.0_55") version.The الشيء الذي لاحظنا هنا، لا يوجد مثل هذه الاختلافات في القيم الافتراضية المخصصة لheapsize | permsize | المعلمات ThreadStackSize في وضع العميل والخادم.

وبالمناسبة، ( http://www.oracle.com/ technetwork / جافا / ergo5-140223.html ). هذا المقتطف المأخوذ من فوق الارتباط.

initial heap size of 1/64 of physical memory up to 1Gbyte
maximum heap size of ¼ of physical memory up to 1Gbyte

وThreadStackSize أعلى في 1.7، في حين يمر المنتدى المفتوح JDK، هناك مناقشات التي تنص على حجم الإطار هو أعلى إلى حد ما في 1.7 الإصدار. الفرق الحقيقي هو يعتقد أنه يمكن أن يكون من الممكن قياس في وقت التشغيل بناء على سلوكك من التطبيق الخاص بك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top