حد منخفض لسلسلة عمليات Java الفردية في Red Hat Linux

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

  •  02-07-2019
  •  | 
  •  

سؤال

أواجه مشكلة على جهاز اختبار يعمل بنظام Red Hat Linux (إصدار kernel هو 2.4.21-37.ELsmp) باستخدام Java 1.6 (1.6.0_02 أو 1.6.0_04).تكمن المشكلة في أنه بمجرد إنشاء عدد معين من سلاسل العمليات في مجموعة سلاسل رسائل واحدة، يصبح نظام التشغيل غير راغب أو غير قادر على إنشاء المزيد.

يبدو أن هذا خاص بإنشاء سلاسل رسائل Java، حيث كان برنامج C Thread-limit قادرًا على إنشاء حوالي 1.5 ألف سلسلة رسائل.بالإضافة إلى ذلك، هذا لا يحدث مع Java 1.4 JVM...يمكنه إنشاء أكثر من 1.4 كيلو بايت من المواضيع، على الرغم من أنه من الواضح أنه يتم التعامل معها بشكل مختلف فيما يتعلق بنظام التشغيل.

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

java.lang.OutOfMemoryError: unable to create new native thread

يبدو أن هذا لا يتأثر بأشياء مثل عدد مؤشرات الترابط المستخدمة من قبل العمليات أو المستخدمين الآخرين أو إجمالي مقدار الذاكرة التي يستخدمها النظام في ذلك الوقت.لا يبدو أن إعدادات JVM مثل Xms وXmx وXss تغير أي شيء أيضًا (وهو أمر متوقع، مع الأخذ في الاعتبار أن المشكلة تتعلق بإنشاء سلسلة عمليات نظام التشغيل الأصلي).

إخراج "ulimit -a" هو كما يلي:

core file size        (blocks, -c) 0
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
max locked memory     (kbytes, -l) 4
max memory size       (kbytes, -m) unlimited
open files                    (-n) 1024
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 10240
cpu time             (seconds, -t) unlimited
max user processes            (-u) 7168
virtual memory        (kbytes, -v) unlimited

لا يبدو أن حد عملية المستخدم هو المشكلة.البحث عن معلومات حول ما يمكن أن يكون خطأ لم يظهر كثيرًا، ولكن هذا المشنور يبدو أنه يشير إلى أن بعض نواة Red Hat على الأقل تقصر العملية على 300 ميجابايت من الذاكرة المخصصة للمكدس، وعند 10 ميجابايت لكل مؤشر ترابط للمكدس، يبدو أن المشكلة قد تكون موجودة (على الرغم من أنها تبدو غريبة وغير محتملة أيضًا).

لقد حاولت تغيير حجم المكدس باستخدام "ulimit -s" لاختبار ذلك، ولكن أي قيمة بخلاف 10240 وJVM لا يبدأ بخطأ:

Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

يمكنني عمومًا التجول في Linux، لكنني لا أعرف الكثير عن تكوين النظام، ولم أتمكن من العثور على أي شيء يعالج هذا النوع من المواقف على وجه التحديد.سيكون موضع تقدير أي أفكار حول النظام أو إعدادات JVM التي قد تسبب ذلك.

التعديلات:تشغيل برنامج الحد من الخيط الذي ذكره طيدة, ، لم يكن هناك أي فشل حتى حاول إنشاء مؤشر الترابط رقم 1529.

لم تحدث المشكلة أيضًا باستخدام 1.4 JVM (تحدث مع 1.6.0_02 و1.6.0_04 JVMs، ولا يمكن اختبارها باستخدام 1.5 JVM في الوقت الحالي).

رمز اختبار الخيط الذي أستخدمه هو كما يلي:

public class ThreadTest {

   public static void main(String[] pArgs) throws Exception {

      try {
         // keep spawning new threads forever
         while (true) {
            new TestThread().start();
         }
      }
      // when out of memory error is reached, print out the number of
      // successful threads spawned and exit
      catch ( OutOfMemoryError e ) {
         System.out.println(TestThread.CREATE_COUNT);
         System.exit(-1);
      }
   }

   static class TestThread extends Thread {
      private static int CREATE_COUNT = 0;
      public TestThread() {
         CREATE_COUNT++;
      }
      // make the thread wait for eternity after being spawned
      public void run() {
         try {
            sleep(Integer.MAX_VALUE);
         }
         // even if there is an interruption, dont do anything
         catch (InterruptedException e) {
         }
      }
   }
}

إذا قمت بتشغيل هذا باستخدام 1.4 JVM، فسيتم تعليقه عندما لا يتمكن من إنشاء المزيد من سلاسل الرسائل ويتطلب القتل -9 (على الأقل حدث ذلك بالنسبة لي).

المزيد من التحرير:

اتضح أن النظام الذي يواجه المشكلة يستخدم نموذج ترابط LinuxThreads بينما يستخدم نظام آخر يعمل بشكل جيد نموذج NPTL.

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

المحلول 2

أدى تحديث النواة إلى إصدار أحدث (2.6.something) باستخدام خيوط NPTL إلى إصلاح هذه المشكلة.

نصائح أخرى

هل نظرت إلى هذا المورد؟تنص على أنه يجب أن تكون قادرًا على تشغيل Thread-Limit للعثور على الحد الأقصى لعدد سلاسل الرسائل ويمكنك تعديله عن طريق تجميع glibc.

هذا مع Ubuntu Linux (ذاكرة الوصول العشوائي سعة 1 جيجابايت)

dsm@localhost:~$ javac ThreadTest.java 
dsm@localhost:~$ java ThreadTest 
8113
dsm@localhost:~$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
dsm@localhost:~$ 

هل يمكنك تجربتها مع JRockit JVM؟IIRC، كان لديه نموذج ترابط مختلف عن المخزون Sun JVM.

الإعدادات في /etc/security/limits.d/90-nproc.conf قد تغلب الخاص بك /etc/security/limits.conf إعدادات.قد يتسبب ذلك في تصرف النظام بطريقة مختلفة كما هو موضح في ulimit -u.

https://bugzilla.redhat.com/show_bug.cgi?id=823030

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