«Java.lang.OutOfMemoryError: не ўдалося стварыць новую тэму роднай»

Мы атрымліваем «java.lang.OutOfMemoryError: не ўдалося стварыць новую родную тэму » на 8 Гб аператыўнай памяці VM пасля 32k патокаў (п.с. -eLF | Grep -c Java)

Тым не менш, «верхні» і «свабодны -m» паказвае 50% вольнай памяці . JDK 64 біт і спрабаваў як з HotSpot і JRockit.Server мае Linux 2.6.18

Мы таксама паспрабавалі памер стэка аперацыйнай сістэмы (ULIMIT -s) падладка і максімальны працэс (ULIMIT -u) абмежаванні, павелічэнне limit.conf, але ўсё дарма.

Таксама мы спрабавалі практычна ўсе магчымыя камбінацыі памеру кучы, захоўваючы яе нізкі, высокі і г.д.

Сцэнар, які мы выкарыстоўваем для запуску прыкладання з'яўляецца

/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties

Дзякуй за адказ.

Мы паспрабавалі рэдагавання /etc/security/limits.conf і ULIMIT, але ўсё-такі, што ж

[[email protected] ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 72192
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 72192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
99
Аперацыйныя сістэмы маюць абмежаванні на колькасць патокаў, якія вы можаце стварыць. Чаму вы ствараеце больш 32k патокаў? Ваша сістэма не хутчэй за ўсё, не мае тысяч працэсарных ядраў, ствараючы так шмат патокаў не з'яўляецца карысным. Выкарыстанне пула патокаў ( ExecutorService ) замест гэтага.
дададзена аўтар Jesper, крыніца
OutOfMemoryError робіць <�Ь> не абавязкова азначае прастору кучы, або "агульны" RAM, быў вычарпаны. У гэтым выпадку ясна, што адмова была з-за АС, не маючы рэсурсаў вылучыць дадатковую нітку. Маючы 50% свабоднай памяці не мае дачынення да гэтай канкрэтнай няўдачы.
дададзена аўтар Andrzej Doyle, крыніца
там, здаецца, некаторыя з адкрытым зыходным кодам, які Lib стварэння патокаў, але не ў стане скончыць/спыніць ніткі належным чынам, можа быць усё ніткі былі створаны і пайшоў у спячы рэжым.
дададзена аўтар Omer, крыніца
Мы спрабавалі выкарыстоўваць ExecutorService, то і лік нітак 32K, гэта таму, што ўсе ніткі вечна жывыя тэмы.
дададзена аўтар Deepak Tewani, крыніца
Якія іншыя рэсурсы, неабходныя для стварэння новых патокаў. Мы былі пад уражаннем, што калі павялічыць аб'ём аператыўнай памяці, то мы можам у стане стварыць больш патокаў. Просьба накіроўваць нас
дададзена аўтар Deepak Tewani, крыніца
Бібліятэка з адкрытым зыходным кодам, які мы выкарыстоўваем у ICE4j бібліятэцы
дададзена аўтар Deepak Tewani, крыніца
Дзякуй за адказ. Мы выкарыстоўваем бібліятэку з адкрытым зыходным кодам і спрабуе загрузіць правяраць. Любая бібліятэка, якая з адкрытым зыходным кодам стварае так шмат патокаў. Але тое, што я не разумею, гэта калі «зверху» паказвае 50% вольнай памяці, то чаму OutOfMemory памылка.
дададзена аўтар Deepak Tewani, крыніца

11 адказы

Гэта не праблема памяці, нават калі імя выключэння высока прапануе так, але праблема аперацыйнай сістэмы рэсурсаў. Вы працуеце з уласных патокаў, то ёсць колькі нітак аперацыйная сістэма дазволіць вашай JVM выкарыстоўваць.

Гэта незвычайная праблема, таму што рэдка трэба так шмат. У вас ёсць шмат безумоўнай нітка нерасту дзе ніткі павінны, але не скончыць?

Вы маглі б разгледзець пытанне перапісвання ў выкарыстанні адзыўныя/Runnables пад кантролем Выканаўца, калі наогул магчыма. Ёсць шмат стандартных выканаўца з розным паводзінамі, якія ваш код можа лёгка кантраляваць.

(Ёсць шмат прычын, чаму колькасць патокаў абмежавана, але яны адрозніваюцца ў залежнасці ад аперацыйнай сістэмы для аперацыйнай сістэмы)

68
дададзена
@DeepakTewani - Магчыма, запуск двух або больш копій вашай праграмы будзе рабіць тое, што вы хочаце? Тым не менш, я думаю, што калі вы працуеце сістэму мала нітак і рэчы па-ранейшаму працуе, хутчэй за ўсё, ваша праграма прайшла тэст на нагрузку. :-)
дададзена аўтар T.E.D., крыніца
Акрамя таго, разгледзець высветліць, як ice4j супольнасць прапанаваць вы павінны вырашыць гэтую праблему. Вы, магчыма, прапусцілі нешта ў дакументацыі.
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Магчыма, але не тое, што я зацікавіў мяне так, я не ведаю, як. Разгледзім адкрыццё новага пытання з просьбай, што на сайце Linux SE.
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Вы зразумелі. Прычына Linux не дае вам больш патокаў не таму, што ён сыходзіць з памяці, але таму, што вы бяжыце ў мяжа, усталяваны самой Linux (гэта можа быць адвольным правілам ці таму, што структура дадзеных, выкарыстоўваная ня якія-небудзь буйней). Звярніце ўвагу, што незалежна ад таго, колькі вы паднімаеце гэты мяжа прыкладанне павінна яшчэ быць у стане справіцца. Я прапаную вам перагледзець свой «паток на злучэнне» дызайн.
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Магчыма, але я думаю, што гэта не дапаможа, як такой. Калі вы бяжыце з рэсурсаў пры тэставанні нагрузкі вы павінны быць у стане кантраляваць тое, што адбываецца ў вашым дадатку. Чаму ў вас ёсць 32000 актыўных патокаў адначасова?
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Я лічу, што гэтая праблема вырашаецца ў сучасных вэб-серверах. Таксама УДП могуць страціць пакеты - які-небудзь прычыне вы не проста выкарыстоўваць вэб-сервер?
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Паколькі OutOfMemory выключэнне павінны былі названыя OutOfResources. Аперацыйная сістэма не можа забяспечыць рэсурс вам трэба. (І аказалася, што я не ведаю ice4j)
дададзена аўтар Thorbjørn Ravn Andersen, крыніца
Мы ствараем 11K кліентаў, якія выкарыстоўваюць 32 K тэмы для чытання, запісу дадзеных на UDP сокетаў. З гэтых 32 Да нітак, 10K ніткі захаваць жывыя тэмы, якія выкарыстоўваюцца, каб трымаць гняздо адкрытым
дададзена аўтар Deepak Tewani, крыніца
Мы таксама паспрабавалі ExecutorService для ніткі, а затым і дадатак стварае 32K тэмы. ExecutorService стварае так шмат патокаў, так як усе патокі, створаныя прыкладаннямі назаўжды жывыя тэмы. Я разумею, што Linux ёсць мяжа прадастаўлення патокаў для прыкладання, але не можам, мы павялічым гэты мяжа?
дададзена аўтар Deepak Tewani, крыніца
дададзена аўтар Deepak Tewani, крыніца
Такім чынам, калі мы будзем выкарыстоўваць 16 Гб аператыўнай памяці (двайны аб'ём памяці, які мы выкарыстоўваем у цяперашні час), то мы ў стане ствараць патокі падвойных лікаў, то цяпер?
дададзена аўтар Deepak Tewani, крыніца
Мы не можам выкарыстоўваць вэб-сервера, так як тое, што мы ствараем кліенты, якія будуць гаварыць з іншымі кліентамі. І кліенты могуць быць ззаду сіметрычным, асіметрычным нацем. Для іх падлучэння, мы выкарыстоўваем бібліятэку ice4j. Што я не ў стане зразумець, калі сервер мае 50% памяці засталося тое, што JVM не ўмее ствараць больш патокаў
дададзена аўтар Deepak Tewani, крыніца
Дзякуй за адказ. Мы выкарыстоўваем бібліятэку ICE4j з адкрытым зыходным кодам і спрабуем загрузіць правяраць. Брус мы павялічваем ліміт патокаў у АС, калі мы ведаем, што ёсць 50% памяці засталося на серверы.
дададзена аўтар Deepak Tewani, крыніца

Цалкам верагодна, што ваша аперацыйная сістэма не дазваляе колькасць патокаў, вы спрабуеце стварыць, ці вы ўдар некаторага мяжы ў JVM. Асабліва, калі гэта такое круглае лік, як 32k, мяжа той ці іншай форме з'яўляецца вельмі верагодным вінаватым.

Вы ўпэўненыя, што вам сапраўды трэба 32k патокаў? Большасць сучасных моў маюць нейкую падтрымку для басейнаў шматразовых патокаў - Я ўпэўнены, што Java ёсць што-то на месцы таксама (напрыклад, ExecutorService , як ужо згадвалася карыстальнік Jesper). Можа быць, вы маглі б запытаць тэмы ад такога пула, замест таго, каб ствараць новыя ўручную.

8
дададзена
Мы ствараем 11K кліентаў, якія выкарыстоўваюць 32 K тэмы для чытання, запісу дадзеных на UDP сокетаў. З гэтых 32 Да нітак, 10K ніткі захаваць жывыя тэмы, якія выкарыстоўваюцца, каб трымаць гняздо адкрытым
дададзена аўтар Deepak Tewani, крыніца
Дзякуй за адказ Мы выкарыстоўваем бібліятэку ICE4j з адкрытым зыходным кодам і спрабуе загрузіць правяраць. Брус мы павялічваем ліміт патокаў у АС, калі мы ведаем, што ёсць 50% памяці засталося на серверы.
дададзена аўтар Deepak Tewani, крыніца

Я сутыкнуўся з такой жа пытанне падчас нагрузачнага тэсту, прычына ў тым, што з віртуальнай машыны Java не можа стварыць новы Java-нітка далей. Ніжэй прыведзены зыходны код віртуальнай машыны Java

if (native_thread->osthread() == NULL) {    
// No one should hold a reference to the 'native_thread'.    
    delete native_thread;   
if (JvmtiExport::should_post_resource_exhausted()) {      
    JvmtiExport::post_resource_exhausted(        
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
        JVMTI_RESOURCE_EXHAUSTED_THREADS, 
        "unable to create new native thread");    
    } THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread");  
} Thread::start(native_thread);`
<�Р> Каранёвая прычына: JVM кідае гэта выключэнне, калі   JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR (рэсурсы вычарпаныя (сродкі памяці   вычарпаныя)) або JVMTI_RESOURCE_EXHAUSTED_THREADS (Ніткі вычарпаныя). </р>

У маім выпадку Jboss стварае занадта шмат патокаў, каб служыць запыт, але ўсё патокі блакуюцца. З-за гэтага, JVM вычэрпваецца з патокамі, а таксама з памяццю (кожны паток мае памяць, якая не вылучаецца, таму што кожны паток блакуецца).

Аналізуемы Java-нітка паліцы назіралі амаль 61K патокі блакуюцца адным з нашага метаду, які з'яўляецца прычынай гэтай праблемы. Ніжэй прыводзіцца частка адвалу разьбы

"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
8
дададзена

Я б рэкамендаваў таксама зірнуць на тэму Stack Size і паглядзець, калі вы атрымліваеце больш патокаў, створаных. Па змаўчанні Thread памер стэка для JRockit 1,5/1,6 </а > 1 МБ для 64-разраднай віртуальнай машыны на АС Linux. 32K ніткі спатрэбіцца значная колькасць фізічнай і віртуальнай памяці ў гонар гэтай патрабаванні.

Паспрабуйце паменшыць памер стэка да 512 КБ у якасці адпраўной кропкі і паглядзець, калі гэта дапамагае ствараць больш патокаў для вашага прыкладання. Я таксама рэкамендую даследаваць гарызантальнае маштабаванне, напрыклад, падзяліўшы вашу апрацоўку прыкладанняў у больш фізічных або віртуальных машынах.

Пры выкарыстанні 64-разраднай VM, праўдзівы мяжа будзе залежаць ад фізічных і віртуальных даступнасці памяці і налады параметраў АС OS, такія як ulimitc. Я таксама рэкамендую наступную артыкул у якасці спасылкі:

OutOfMemoryError: не ўдалося стварыць новую родную нітка - Праблема Demystified </а>

4
дададзена

У мяне была тая ж праблема, з-за прывідных працэсаў, якія ня з'яўляюцца пры выкарыстанні зверху ў баш. Гэта прадухіліла JVM на нераст больш нітак.

Для мяне, гэта вырашыць, пералічваючы ўсе працэсы Java з JPS (проста выканаць JPS у абалонцы) і забіў іх паасобку, выкарыстоўваючы забіць -9 PID каманды Баш для кожнага працэсу прывід.

Гэта можа дапамагчы ў некаторых сітуацыях.

3
дададзена

Перш за ўсё, я не вінаваты, што шмат OS/VM .. хутчэй, распрацоўшчык, які напісаў код, які стварае ооочень шмат Тэмы . У асноўным дзесьці ў кодзе (ці 3-й партыі) <�моцны> шмат патокаў ствараюцца без кіравання .

Уважліва вывучыце stacktraces/код і кантраляваць колькасць патокаў, якiя ствараюцца ў. Звычайна ваша прыкладанне не трэба вялікая колькасць нітак, калі ён робіць гэта іншая праблема.

2
дададзена
Гэта не рашэнне пытання.
дададзена аўтар ftrujillo, крыніца

У вас ёсць шанец сутыкнуцца з java.lang.OutOfMemoryError: Не атрымалася стварыць новы родны ніткі кожны раз, калі віртуальная машына запытвае новы струмень ад аперацыйнай сістэмы. Кожны раз, калі асноўнай АС не можа вылучыць новы родны паток, гэта OutOfMemoryError будзе адкінуты. Дакладны мяжа для ўласных патокаў вельмі залежыць ад платформы, такім чынам, яго рэкамендую, каб высветліць гэтыя абмежаванні, выканаўшы тэст, падобны на прыклад ніжэй спасылкі. Але, у цэлым, сітуацыя выклікае java.lang.OutOfMemoryError: Немагчыма стварыць новую родную нітка праходзіць праз наступныя этапы:

  1. Новы Java паток запытваецца дадаткам, якія працуюць ўнутры JVM
  2. JVM натыўны код перадае запыт на стварэнне новага выхадца нітка АС АС спрабуе стварыць новую родную нітка, якая патрабуе памяці, якія будуць выдзелены ніткі
  3. Аперацыйная сістэма адмовіць Ураджэнец размеркаванне памяці альбо таму, што ў 32-разраднасці працэсу Java патраціла яго адрасная прастора памяці - напрыклад, (2-4) ГБ памер працэсу мяжа быў уражаны - ці віртуальная памяць АС цалкам была знясіленыя
  4. <�Літый> The java.lang.OutOfMemoryError: Немагчыма стварыць новы родны памылка нітка выкідваецца.

Reference: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread

1
дададзена

Калі ваша праца не атрымоўваецца з-за OutOfMemmory на вузлах вы можаце Твік вашага колькасці макс карт і рэдуктараў і JVM выбірае для кожнага з іх. mapred.child.java.opts (па змаўчанні 200Xmx) звычайна павінен быць павялічаны на аснове вашых вузлоў дадзеных канкрэтных апаратных сродкаў.

This link might be helpful... pls check

1
дададзена
Мы ўсе ўжо спрабавалі гэта змяненне, якое даецца па гэтай спасылцы. Але вынік той жа :(
дададзена аўтар Deepak Tewani, крыніца

канфігурацыя JBoss мае некаторыя праблемы, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms і X абмяжоўваюць выкарыстанне памяці JBoss, у наладжаным значэнне, таму з 8Gb ў вас ёсць сервер толькі Ussing 512M + некаторыя дадатковы для сваёй мэты, павялічыць гэты лік, не забудзьцеся пакінуць трохі свободнога для аперацыйнай сістэмы і іншых рэчаў працуе там, і можа быць, вы атрымаеце гэта працуе, нягледзячы дэ заганным кода. Выпраўленне кода было б занадта добра, калі вы можаце.

1
дададзена

У мяне была такая ж праблема, і аказалася, што няправільнае выкарыстанне ў Java API. Я ініцыялізацыя построителя метаду пакетнай апрацоўкі, што было тое, што не павінны быць initiallized больш чым адзін раз.

У асноўным, я раблю нешта накшталт:

for (batch in batches) {
    process_batch(batch)
}

def process_batch(batch) {
    var client = TransportClient.builder().build()
    client.processList(batch)
}

калі я павінен быў зрабіць гэта:

for (batch in batches) {
    var client = TransportClient.builder().build()
    process_batch(batch, client)
}

def process_batch(batch, client) {
    client.processList(batch)
}
0
дададзена

Для таго, каб высветліць, якія працэсы стварэння патоку спрабуюць:

ps huH

Я звычайна перанакіраваць выснову ў файл і файл аналізу ў аўтаномным рэжыме (гэты лік патокаў для кожнага працэсу, як чакаецца, ці не)

0
дададзена