RE:NODE

Minecraft13 წუთის საკითხავი

Minecraft-ის JVM flag-ები და Java-ს რომელი ვერსია გაუშვა

Minecraft-ის რომელ ვერსიას Java-ს რომელი ვერსია სჭირდება, როგორ განისაზღვროს heap container-ის ლიმიტის მიხედვით და რას აკეთებს Aikar-ის ყველა flag.

0 მკითხველი

JVM-თან დაკავშირებული ორი გადაწყვეტილება Minecraft სერვერზე ყველა დანარჩენ პარამეტრზე მეტად მოქმედებს: Java-ს რომელ ვერსიას გაუშვებ და რამდენ heap-ს მისცემ. პირველს თითო Minecraft ვერსიაზე ერთი სწორი პასუხი აქვს და აზრისთვის ადგილი არ არის. მეორეში ხალხი ორივე მიმართულებით ცდება: 2 GB container-ს 2 GB heap-ს აძლევენ და უკვირთ, რატომ კვდება, ან ოცმოთამაშიან სერვერს 16 GB-ს აძლევენ და უკვირთ, რატომ გაუარესდა პაუზები.

ამ ორის შემდეგ ყველაფერი garbage collector-ის დაზუსტებაა, რაც რეალურ, თუმცა ზომიერ გაუმჯობესებას იძლევა - უფრო თანაბარ tick დროებს და არა უფრო მაღალ ჭერს. Aikar-ის flag-ები ამისთვის გონივრული ნაგულისხმევია, წლებია ასეა, და ეს პოსტი განმარტავს, რას აკეთებს თითოეული მათგანი, რომ თავად გადაწყვიტო, დატოვო თუ არა.

Java-ს რომელი ვერსია Minecraft-ის რომელ ვერსიას#

Minecraft-ის სერვერი კომპილირებულია Java-ს კონკრეტული რელიზისთვის. Java-ს უფრო ახალი ვერსია თითქმის ყველა შემთხვევაში უფრო ძველ Minecraft-ს უშვებს; უფრო ძველი Java უფრო ახალ Minecraft-ს არასოდეს უშვებს.

Minecraftმინიმალური Javaპრაქტიკაში
1.8 - 1.16.5Java 8Java 8 ან 11. უფრო ახალი Java ზოგ ძველ plugin-ს არღვევს
1.17 - 1.17.1Java 16Java 17 მუშაობს და მისი პოვნა უფრო ადვილია
1.18 - 1.20.4Java 17Java 21-იც მუშაობს Paper-ისთვის
1.20.5 და უფრო ახალიJava 211.21-ის ყველა ვერსიის ჩათვლით

წარუმატებლობა, როცა შეცდები, ცალსახაა:

code
Error: LinkageError occurred while loading main class io.papermc.paperclip.Mainjava.lang.UnsupportedClassVersionError: io/papermc/paperclip/Main has beencompiled by a more recent version of the Java Runtime (class file version 65.0),this version of the Java Runtime only recognizes class file versions up to 61.0

Class file 65 არის Java 21, 61 - Java 17, 60 - Java 16, 55 - Java 11, 52 - Java 8. წაიკითხე ორი რიცხვი, დააყენე უფრო მაღალი და მორჩა.

საპირისპირო მიმართულება უფრო დახვეწილია. 1.12.2-ის გაშვება Java 17-ზე ან 21-ზე ხშირად მუშაობს და ზოგჯერ არა, რადგან ძველი plugin-ები და ძველი ბიბლიოთეკების ვერსიები JDK-ს შიდა ნაწილებში reflection-ს იყენებენ, რომელიც შემდეგმა რელიზებმა დახურა. თუ legacy სერვერს ინახავ, დარჩი იმ Java-ზე, რომლითაც თამაში მოვიდა. თუ modpack-ს უშვებ, პაკეტის საკუთარი დოკუმენტაცია Java-ს ვერსიას ასახელებს და დაუჯერე - modded Minecraft ავარიების გარეშე ამ კონკრეტული ნაღმებით სავსე ველის დანარჩენ ნაწილს ფარავს.

RE:NODE-ზე Java-ს ვერსია სერვერის შექმნისას Minecraft-ის ვერსიას ესადაგება, ამიტომ ახალი 1.21 სერვერი უკვე Java 21-ზეა. თუ სხვა jar-ს თავად ატვირთავ, სანამ გაიკვირვებ, რატომ არ იტვირთება, Startup tab შეამოწმე.

Java-ს რომელი build დააყენო#

სწორი ვერსიის ნებისმიერი OpenJDK build Minecraft სერვერს სწორად გაუშვებს. განსხვავებები შეფუთვასა და მხარდაჭერაშია და არა წარმადობაში.

  • Eclipse Temurin Adoptium-დან ჩვეულებრივი ნაგულისხმევია: უფასო, კარგად გამოცდილი, ყველა LTS ვერსიისთვის ხელმისაწვდომი.
  • Amazon Corretto მეორე გავრცელებული არჩევანია, მხარდაჭერის ხანგრძლივი ვადებით.
  • Microsoft Build of OpenJDK და Azul Zulu ასევე შესანიშნავია.
  • Oracle JDK მუშაობს, მაგრამ ლიცენზიას შეიცავს, რომელიც კომერციულ გამოყენებამდე უნდა წაიკითხო.

აირჩიე გრძელვადიანი მხარდაჭერის რელიზები - 8, 11, 17, 21 - და არა ექვსთვიანი შუალედური რელიზი, რადგან plugin-ის ავტორები LTS-ზე ტესტავენ. Linux-ზე დააყენე headless პაკეტი (openjdk-21-jre-headless Debian-სა და Ubuntu-ზე), რომ გრაფიკულ ბიბლიოთეკებს არ ჩატვირთავ, რომლებსაც სერვერი არასოდეს იყენებს.

GraalVM პერიოდულად ჩნდება როგორც წარმადობის მოგება. შედეგები Minecraft-ზე არათანმიმდევრულია: ზოგ დატვირთვაზე რამდენიმე პროცენტს იგებს, ზოგზე კარგავს. ეს შეცდომა არ არის, მაგრამ ის უფასო განახლებაც არ არის, როგორადაც ზოგჯერ აღწერენ, და სანამ ვალდებულებას აიღებ, საკუთარ სერვერზე უნდა გაზომო.

Heap-ის ზომა და სხვაობა -Xmx-სა და გეგმას შორის#

-Xms საწყისი heap-ია, -Xmx - მაქსიმალური. დააყენე ისინი ერთ მნიშვნელობაზე. JVM ფიქსირებული ზომის container-ს მეხსიერებას სასარგებლოდ ვერ დაუბრუნებს, heap-ის ზომის შეცვლა პაუზებს ჯდება, ხოლო ტოლი წყვილი ნიშნავს, რომ მეხსიერების გრაფიკი რაღაცას გეუბნება და არა ხერხისებრ ტალღას აჩვენებს.

რასაც ხალხი გამორჩება, ისაა, რომ -Xmx სერვერის მეხსიერების მოხმარება არ არის. ეს heap-ია. მის გარდა JVM-ს სჭირდება:

  • Metaspace, ჩატვირთული კლასებისთვის. plugin-ებით დატვირთულ სერვერს აქ 150-300 MB შეიძლება ჰქონდეს, modpack-ს კი გაცილებით მეტი.
  • Code cache, JIT-ით კომპილირებული მეთოდებისთვის. ათეულობით მეგაბაიტი, რომელიც uptime-თან ერთად იზრდება.
  • Thread stack-ები, დაახლოებით 1 MB თითოეული, ათეულობით thread-ით.
  • Direct byte buffer-ები, რომლებსაც Netty ქსელისთვის იყენებს. Heap-ს გარეთაა და -Xmx-ისთვის უხილავია.
  • თავად GC-ის სტრუქტურები, რომლებიც G1-ისთვის heap-ის მნიშვნელოვანი პროცენტია.

ამიტომ Minecraft სერვერის მთლიანი რეზიდენტული მეხსიერება მშვიდად -Xmx პლუს 400 MB-დან 1 GB-მდეა, modded სერვერზე - მეტი. თუ ეს ჯამი container-ის ლიმიტს გადაცდება, ბირთვი პროცესს აჩერებს და არ არის არც Java exception, არც crash report და არც მინიშნება ლოგში, გარდა იმისა, რომ ის ხაზის შუაში წყდება.

გეგმის მეხსიერება-Xmx დააყენედარჩენილი მარაგი
2 GB1536M512 MB
4 GB3G1 GB
6 GB5G1 GB
10 GB8G2 GB
14 GB12G2 GB

ესენი განზრახ კონსერვატიულია. დაიწყე მათგან, დააკვირდი მეხსიერების გრაფიკს ერთი კვირა რეალური დატვირთვისას და გაზარდე -Xmx, თუ heap ნამდვილად შემზღუდველია. მისი გაზრდა იმიტომ, რომ გრაფიკზე გამოუყენებელი მეხსიერებაა, ნელი სერვერის ისეთ სერვერად გადაქცევის გზაა, რომელიც თავისით ირთვება.

მასთან დაკავშირებული შეცდომაა რწმენა, რომ დიდი heap უფრო სწრაფი სერვერია. ეს ასე არ არის. Java არ იყენებს მეხსიერებას, რომელიც არ მოუთხოვიათ, და ყოველი G1 collection-ი ცოცხალ ობიექტებს სკანირებს და აკოპირებს, ამიტომ დიდი heap ნიშნავს მეტ მუშაობას ერთ ციკლზე და უფრო გრძელ უარეს პაუზებს. ოცმოთამაშიანი Paper სერვერი 6 GB-ზე გონივრული flag-ებით ჩვეულებრივ უკეთ tick-ავს, ვიდრე იგივე სერვერი 16 GB-ზე. რამდენი RAM სჭირდება Minecraft სერვერს მოთამაშეების რაოდენობის მიხედვით რიცხვებს შეიცავს, ხოლო node-ის მეხსიერების ლიმიტები ახსნილი იმავე არგუმენტს აპლიკაციის მხრიდან იძლევა.

Aikar-ის flag-ები, ხაზ-ხაზ#

Minecraft-ისთვის G1-ზე კანონიკური flag-ების ნაკრები წლებია სტაბილურია. 12 GB-ზე ნაკლები heap-ისთვის:

bash
$ java -Xms5G -Xmx5G \    -XX:+UseG1GC \    -XX:+ParallelRefProcEnabled \    -XX:MaxGCPauseMillis=200 \    -XX:+UnlockExperimentalVMOptions \    -XX:+DisableExplicitGC \    -XX:+AlwaysPreTouch \    -XX:G1NewSizePercent=30 \    -XX:G1MaxNewSizePercent=40 \    -XX:G1HeapRegionSize=8M \    -XX:G1ReservePercent=20 \    -XX:G1HeapWastePercent=5 \    -XX:G1MixedGCCountTarget=4 \    -XX:InitiatingHeapOccupancyPercent=15 \    -XX:G1MixedGCLiveThresholdPercent=90 \    -XX:G1RSetUpdatingPauseTimePercent=5 \    -XX:SurvivorRatio=32 \    -XX:+PerfDisableSharedMem \    -XX:MaxTenuringThreshold=1 \    -jar paper.jar --nogui

12 GB-ის ან მეტი heap-ისთვის ხუთი მნიშვნელობა იცვლება: G1NewSizePercent=40, G1MaxNewSizePercent=50, G1HeapRegionSize=16M, G1ReservePercent=15, InitiatingHeapOccupancyPercent=20. ყველაფერი დანარჩენი უცვლელია.

რას აკეთებენ ისინი:

  • UseG1GC ირჩევს garbage collector-ს. Java 9-იდან და უფრო ახალზე ის უკვე ნაგულისხმევია, მაგრამ მისი დაწერა ნიშნავს, რომ შეცვლილი ნაგულისხმევი ვერ გაგაკვირვებს.
  • ParallelRefProcEnabled პაუზისას სუსტ და რბილ reference-ებს პარალელურად ამუშავებს. Minecraft მათ უამრავს ქმნის და ეს ნაკრების ერთ-ერთი ყველაზე ნათელი მოგებაა.
  • MaxGCPauseMillis=200 მიზანია და არა დაპირება. G1 თავის სამუშაოს ისე ზომავს, რომ ამის ქვემოთ დარჩეს. გაითვალისწინე, რას ნიშნავს 200 ms 50 ms tick-იანი თამაშისთვის: მიზნის ტოლი პაუზა ოთხ tick-ს გამოტოვებს. მისი 50-მდე შემცირება 50 ms პაუზებს არ გაძლევს, გაძლევს გაცილებით ხშირ collection-ებს.
  • UnlockExperimentalVMOptions საჭიროა, რადგან ქვემოთ მოცემული რამდენიმე G1 ოფცია ექსპერიმენტულად იყო მონიშნული.
  • DisableExplicitGC JVM-ს System.gc() გამოძახებებს აიგნორებინებს. plugin-ები და ბიბლიოთეკები ხანდახან მას იძახებენ და ყოველი გამოძახება სრული stop-the-world collection-ია, რომელიც არ გჭირდებოდა.
  • AlwaysPreTouch სტარტისას heap-ის ყველა გვერდზე წერს, ამიტომ მეხსიერება წინასწარ იმაგრებს და თამაშისას page fault-ებს თავიდან იცილებს. კომპრომისი: უფრო ნელი გაშვება და მეხსიერების გრაფიკი, რომელიც პირველივე წამიდან -Xmx-ზე დგას, რაც პანელის გრაფიკს "რამდენია გამოყენებული" ინდიკატორად უსარგებლოს ხდის.
  • G1NewSizePercent=30 და G1MaxNewSizePercent=40 young generation-ს G1-ის ნაგულისხმევ 5%-ზე ბევრად მეტად ზრდის. Minecraft უზარმაზარ რაოდენობას ანაწილებს და უმეტესობა tick-ში ან ორში კვდება, ამიტომ დიდი eden ნიშნავს ნაკლებ collection-ს და old generation-ში გაცილებით ნაკლებ გადაყვანას.
  • G1HeapRegionSize=8M G1-ის region-ებს ზრდის. ობიექტები, რომლებიც region-ის ნახევარზე დიდია, "humongous"-ია და განსაკუთრებულად გამოიყოფა, რაც ნელია; Minecraft-ის chunk და palette მასივები საკმარისად დიდია, რომ ნაგულისხმევ region ზომაზე ამას მიაღწიონ.
  • G1ReservePercent=20 heap-ის ნაწილს თავისუფლად ტოვებს, რომ evacuation-ს ყოველთვის ჰქონდეს, სად წავიდეს. მის გარეშე იღებ to-space exhaustion-ს, რომელიც სრულ collection-ში გადადის.
  • G1HeapWastePercent=5 და G1MixedGCCountTarget=4 mixed collection-ებს უფრო ადრე იწყებს და ნაკლებ, მაგრამ უფრო დიდ ნაბიჯებში ამთავრებს.
  • InitiatingHeapOccupancyPercent=15 concurrent marking ციკლს ნაგულისხმევი 45%-ის ნაცვლად heap-ის 15%-იანი დატვირთვისას იწყებს. დიდ young generation-თან კომბინაციაში ეს old generation-ს სუფთას ინახავს და ნორმალური მუშაობისას სრულ collection-ებს მთლიანად თავიდან აცილებს.
  • G1MixedGCLiveThresholdPercent=90 mixed collection-ებს საშუალებას აძლევს, region-ები, რომლებიც 90%-მდე ცოცხალია, გაასუფთაონ, ასე რომ არაფერი რჩება სამუდამოდ დაუგროვებელი.
  • G1RSetUpdatingPauseTimePercent=5 remembered-set-ის მოვლას პაუზიდან concurrent დროში გადააქვს.
  • SurvivorRatio=32 და MaxTenuringThreshold=1 ერთად ნიშნავს, რომ ობიექტები ან მაშინვე გროვდება, ან ერთხელ გადარჩენის შემდეგ გადაჰყავთ, survivor სივრცეებს შორის წინ და უკან კოპირების ნაცვლად. Minecraft-ის განაწილების ნიმუშისთვის კოპირება ფუჭი სამუშაოა.
  • PerfDisableSharedMem JVM-ს ხელს უშლის, წარმადობის მრიცხველები /tmp-ში memory-mapped ფაილში ჩაწეროს. დატვირთულ ან ნელ დისკზე ამ ჩაწერამ მთელი JVM შეიძლება შეაჩეროს, ხოლო არაფერს, რასაც შენ იყენებ, ეს ფაილი არ სჭირდება.

გამოქვეყნებულ ვერსიაში ასევე ნახავ -Dusing.aikars.flags=https://mcflags.emc.gs და -Daikars.new.flags=true-ს. ისინი ეფექტის გარეშე მარკერებია, რომ crash report-ის მკითხველმა დაინახოს, flag-ები გამოყენებული იყო.

ერთი არასავალდებულო დამატება Java 17-ზე და უფრო ახალზე: --add-modules=jdk.incubator.vector Paper-ს საშუალებას აძლევს, მათემატიკის ზოგი ნაწილისთვის incubating Vector API გამოიყენოს. JVM სტარტისას გაფრთხილებას წერს incubator მოდულის გამოყენების შესახებ, რაც მოსალოდნელია და შეცდომა არ არის.

Collector-ები: G1, ZGC და ისინი, რომლებიც გამოსატოვებელია#

G1 პასუხია პრაქტიკულად ყველა Minecraft სერვერისთვის. ის generational-ია, თავისი სამუშაოს უმეტესობას concurrent აკეთებს და ზემოთ მოცემული flag-ების ნაკრები ზუსტად ამ დატვირთვაზეა გამართული.

ZGC heap-ის ზომის მიუხედავად მილიწამზე ნაკლებ პაუზებს ისახავს მიზნად. Java 21-ზე generational ვერსია ირთვება -XX:+ZGenerational-ით; უფრო ახალ რელიზებზე ის ნაგულისხმევია და non-generational რეჟიმი გასასვლელისკენ მიდის, ამიტომ გამოყენებამდე შეამოწმე, რას ელის შენი JDK. ის ნამდვილად ეხმარება ძალიან დიდ heap-ებს - 24 GB modded სერვერს მანქანაზე, სადაც ბირთვები მეტია - და G1-ზე მეტ CPU-სა და off-heap მეხსიერებას ხარჯავს. ნუ გამოიყენებ მას 4 GB გეგმაზე ერთნახევარი ბირთვით; გადაიხდი concurrency-ში, რომელიც არ გაგიჭირვებია.

Shenandoah, ხელმისაწვდომი Temurin და Corretto build-ებში, მეორე დაბალპაუზიანი collector-ია და მსგავსად იქცევა. ორივეს გამოცდა მხოლოდ მას შემდეგ ღირს, რაც GC ლოგით დაამტკიცებ, რომ გაწუხებს პაუზის დრო და არა tick-ის სამუშაო.

Parallel GC (-XX:+UseParallelGC) throughput collector-ია გრძელი stop-the-world პაუზებით. 1-2 GB სერვერზე ეს პაუზები მაინც მოკლეა და ის G1-ზე ნაკლებ CPU-ს იყენებს, ამიტომ ის დასაცავი არჩევანია ყველაზე პატარა გეგმებზე. დაახლოებით 4 GB-ზე ზემოთ ის არასწორი ხელსაწყოა.

CMS აღარ არსებობს. ის Java 14-ში ამოიღეს და ნებისმიერი გზამკვლევი, რომელიც -XX:+UseConcMarkSweepGC-ს გირჩევს, მანამდეა დაწერილი და დახურე.

flag-ები, რომლებიც საერთოდ არაფერს აკეთებს და მაინც ტრიალებს: -XX:+UseFastAccessorMethods და -XX:+AggressiveOpts JVM-იდან წლების წინ ამოიღეს, -Xincgc CMS-თან ერთად წავიდა, ხოლო -XX:+OptimizeStringConcat ათი წელია ნაგულისხმევი ქცევაა. -Xmn-ის G1-თან ერთად დაყენება უსარგებლოზე უარესია: ის young generation-ის ზომას ამაგრებს და G1-ს ადაპტაციას უკრძალავს, რაც ზემოთ მოცემული flag-ების მიზნის საპირისპიროა.

მეხსიერების დიაგნოსტიკა: ლოგები, dump-ები და ოთხი out-of-memory შეცდომა#

ჩართე GC logging, სანამ დაგჭირდება. ის თითქმის არაფერი ჯდება და ერთადერთი გზაა კითხვაზე "ეს ლაგი პაუზა იყო?" პასუხის გასაცემად.

bash
-Xlog:gc*:file=logs/gc.log:time,uptime,level,tags:filecount=5,filesize=10M

რას დაუწყო ძებნა შედეგში. ხაზები Pause Young (Normal) (G1 Evacuation Pause) რამდენიმე ათეულ მილიწამზე სერვერის ნორმალური მუშაობაა. Pause Young (Concurrent Start) marking ციკლის დაწყებაა, რაც რეგულარულად და ჩუმად უნდა ხდებოდეს. ორი ხაზი, რომელიც ნიშნავს, რომ რაღაც არასწორია: To-space exhausted, რაც ნიშნავს, რომ G1-ს evacuation-ისთვის ადგილი გამოელია და მეტი reserve ან heap სჭირდება, და Pause Full (Allocation Failure), რაც ნიშნავს, რომ G1-მ დანებდა და ერთნაკადიანი სრული collection გააკეთა. სრული GC 6 GB heap-ზე რამდენიმეწამიანი გაყინვაა და მოთამაშეები მას crash-ად შეგატყობინებენ.

out-of-memory შეცდომები ოთხი განსხვავებული პრობლემაა ერთი სახელით:

  • java.lang.OutOfMemoryError: Java heap space - heap ნამდვილად სავსეა. ან გაზარდე -Xmx არსებული მარაგის ფარგლებში, ან იპოვე, რა იჭერს მეხსიერებას. spark heap summary კლასებს ასახელებს.
  • java.lang.OutOfMemoryError: Metaspace - ძალიან ბევრი ჩატვირთული კლასი. plugin სერვერზე ეს თითქმის ყოველთვის /reload-ის განმეორებითი გამოყენებით არის გამოწვეული, რომელიც ძველ class loader-ებს ტოვებს. ნაცვლად ამისა, სწორად გადატვირთე და თუ ნამდვილად მეტი გჭირდება, -XX:MaxMetaspaceSize=512M.
  • java.lang.OutOfMemoryError: unable to create new native thread - პროცესის ან მეხსიერების ლიმიტია და არა heap-ის პრობლემა. ჩვეულებრივ plugin ქმნის thread-ებს შეზღუდვის გარეშე.
  • საერთოდ არანაირი შეცდომა და ლოგი უბრალოდ წყდება - container-მა მეხსიერების ლიმიტს მიაღწია და გარედან გაჩერდა. Java ამას წინასწარ ვერ ხედავს, სწორედ ამიტომ არსებობს მარაგის ცხრილი.

პირველ შემთხვევაში -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumps dump-ს წერს, რომლის ანალიზიც შეგიძლია. გაითვალისწინე, რომ dump დაახლოებით heap-ის ზომისაა, ამიტომ 10 GB სერვერი 10 GB ფაილს წერს დისკზე, რომელსაც შეიძლება მისთვის ადგილი არ ჰქონდეს.

როცა გაიგებ, რომ მეხსიერება პრობლემა არ არის, შემდეგი გაჩერება თავად tick-ია: რატომ ეცემა TPS და რა ვქნათ, შემდეგ spark-ის რეპორტის კითხვა, რომ იპოვო პასუხისმგებელი plugin ან chunk. რას ნიშნავს tick rate სინამდვილეში განმარტავს, რატომ შეიძლება სერვერი 20 TPS-ზე იდგეს და მაინც ცუდად იგრძნობოდეს.

გაანგარიშებული მაგალითი 6 GB გეგმაზე#

ოცი მოთამაშე, Paper 1.21, თხუთმეტი plugin, წინასწარ გენერირებული სამყარო 5000-ბლოკიანი საზღვრით.

bash
$ java -Xms5G -Xmx5G -XX:+UseG1GC -XX:+ParallelRefProcEnabled \    -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions \    -XX:+DisableExplicitGC -XX:+AlwaysPreTouch \    -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 \    -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 \    -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 \    -XX:InitiatingHeapOccupancyPercent=15 \    -XX:G1MixedGCLiveThresholdPercent=90 \    -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 \    -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 \    -Xlog:gc*:file=logs/gc.log:time,uptime:filecount=5,filesize=10M \    -jar paper.jar --nogui

6 GB გეგმიდან 5G, რაც გიგაბაიტს ტოვებს metaspace-ისთვის, code cache-ისთვის, Netty buffer-ებისთვის და თავად JVM-ისთვის. Java 21, რადგან Minecraft-ის ვერსია მას მოითხოვს. GC logging ჩართულია, რადგან უფასოა. და ეს არის JVM-ის წვლილის დასასრული - თუ ეს სერვერი მაინც ლაგავს, პასუხი Paper-ის კონფიგურაციასა და plugin-ების სიაშია და არა კიდევ ერთ flag-ში. Paper-ის ოპტიმიზაციის გზამკვლევი შემდეგი გაჩერებაა, ხოლო სერვერის დატვირთვის გრაფიკის კითხვა გეუბნება, CPU-ს, მეხსიერებას თუ დისკს უყურებ.

პანელზე დაფუძნებულ ჰოსტზე flag-ები shell სკრიპტში კი არა, გაშვების ბრძანებაში ან JVM არგუმენტების ველში იწერება. RE:NODE-ზე ეს Startup tab-ია, თამაშისა და გარემოს ცვლადების გვერდით, ხოლო კონსოლი მეხსიერებას გეგმის ლიმიტის მიმართ გრაფიკზე აჩვენებს, ასე რომ მაშინვე ხედავ, AlwaysPreTouch-მა ხომ არ გაასწორა ხაზი ზედა ნაწილში.

FAQ#

უნდა დავაყენო თუ არა -Xmx ჩემი გეგმის მთელ ზომაზე?

არა. heap მხოლოდ ის ნაწილია, რასაც JVM იყენებს, დანარჩენი - metaspace, code cache, thread stack-ები, ქსელის buffer-ები - მის გარეთ ცხოვრობს. პატარა გეგმაზე დატოვე 500 MB, დიდზე - 1-2 GB, თორემ container ლიმიტის გადაჭარბების გამო გაჩერდება და მის ასახსნელად Java-ს შეცდომა არ იქნება.

მუშაობს თუ არა Aikar-ის flag-ები Java 21-ზე?

დიახ. ნაკრების ყველა flag კვლავ მოქმედია მიმდინარე LTS რელიზებზე და დაზუსტება Minecraft-ის განაწილების ნიმუშისთვის კვლავ შესაფერისია. ერთადერთი, რაც შეიცვალა, ისაა, რომ -XX:+UseG1GC ახლა ნაგულისხმევს აცხადებს და არა ცვლის.

გამოასწორებს თუ არა მეტი RAM ჩემს ლაგს?

მხოლოდ თუ მეხსიერება არის ის, რაც აკლია. თუ მეხსიერების გრაფიკი ლიმიტზე ბევრად დაბლა დგას, სანამ სერვერი ლაგავს, ბოთლის ყელი tick-ია - plugin, entity-ების რაოდენობა ან view distance, რომელსაც CPU ვერ ატარებს. ამ სიტუაციაში heap-ის დამატება პაუზებს უფრო გრძელს ხდის და არა უფრო მოკლეს.

რატომ იყენებს ჩემი სერვერი მუდმივად ზუსტად თავის მაქსიმალურ მეხსიერებას?

-XX:+AlwaysPreTouch. ის მთელ heap-ს სტარტისას ამაგრებს, განზრახ, ამიტომ რეზიდენტული მეხსიერება -Xmx-ის ტოლია პირველივე წამიდან. ეს არც leak-ია და არც პრობლემა, მაგრამ ნიშნავს, რომ მეხსიერების გრაფიკი აღარ გიჩვენებს, heap-ის რა ნაწილია ცოცხალი. ამისთვის გამოიყენე GC ლოგი ან spark.

შემიძლია თუ არა Minecraft 1.8-ის plugin-ების გაშვება Java 21-ზე?

ჩვეულებრივ არა. ძველი plugin-ები JDK-ს შიდა ნაწილებში იჭრებიან, რომლებიც უფრო ახალმა რელიზებმა დახურა, და წარუმატებლობები ბუნდოვანია და არა მკაფიო. legacy სერვერმა უნდა გაუშვას Java-ს ის ვერსია, რომელიც აშენებისას მიმდინარე იყო.

უფრო მნიშვნელოვანია თუ არა garbage collector-ის არჩევანი, ვიდრე flag-ები?

უმეტეს სერვერზე - არა. G1 დაზუსტებული flag-ებით სწორი პასუხია დაახლოებით 2 GB-იდან დაახლოებით 16 GB heap-მდე, რაც თითქმის ყველას ფარავს. collector-ის შეცვლა იმის გასაცდელია, რაც მას შემდეგ უნდა გააკეთო, რაც GC ლოგმა გაჩვენებს, რომ პრობლემა კონკრეტულად პაუზის დროა.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000