วิธีจัดการกับข้อผิดพลาด“ java.lang.OutOfMemoryError: Java heap space” ข้อผิดพลาด?


416

ฉันกำลังเขียนฝั่งไคลเอ็นต์สวิงแอพลิเคชัน (นักออกแบบตัวอักษรกราฟิก) ในJava 5 เมื่อเร็ว ๆ นี้ฉันพบjava.lang.OutOfMemoryError: Java heap spaceข้อผิดพลาดเนื่องจากฉันไม่ได้ระมัดระวังในการใช้หน่วยความจำ ผู้ใช้สามารถเปิดได้ไม่ จำกัด จำนวนไฟล์และโปรแกรมเก็บวัตถุที่เปิดอยู่ในหน่วยความจำ หลังจากที่มีการวิจัยอย่างรวดเร็วผมพบว่าการยศาสตร์ใน 5.0 โปรแกรม Java Virtual Machineและคนอื่น ๆ บอกว่าบน Windows เครื่อง JVM 64MBค่าเริ่มต้นขนาดสูงสุดกองเป็น

ด้วยสถานการณ์เช่นนี้ฉันจะจัดการกับข้อ จำกัด นี้ได้อย่างไร

ฉันสามารถเพิ่มขนาดฮีพสูงสุดโดยใช้ตัวเลือกบรรทัดคำสั่งเป็นจาวา แต่นั่นต้องใช้การหา RAM ที่มีอยู่และเขียนโปรแกรมเรียกใช้หรือสคริปต์บางตัว นอกจากนี้ยังเพิ่มขึ้นบางส่วนจำกัดสูงสุดไม่ได้ในท้ายที่สุดได้รับการกำจัดของปัญหา

ฉันสามารถเขียนรหัสของฉันใหม่เพื่อคงออบเจ็กต์ไปยังระบบไฟล์บ่อยครั้ง (การใช้ฐานข้อมูลเป็นสิ่งเดียวกัน) เพื่อเพิ่มหน่วยความจำ มันสามารถใช้งานได้ แต่ก็อาจทำงานได้มากเช่นกัน

หากคุณสามารถชี้ให้ฉันเห็นรายละเอียดของแนวคิดข้างต้นหรือทางเลือกบางอย่างเช่นหน่วยความจำเสมือนอัตโนมัติขยายขนาดฮีปแบบไดนามิกนั่นจะยอดเยี่ยม


ขนาดฮีพสูงสุดเริ่มต้นคือ 64 MB มาก่อน J2SE 5.0 สำหรับ J2SE 8.0 ข้อมูลดู "มูลฝอยนักการยศาสตร์" ที่docs.oracle.com/javase/8/docs/technotes/guides/vm/...
Andy Thomas

หากคุณมาที่นี่เนื่องจากคำถาม OOM ทุกคำถามติดกับคำถามนี้ตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบแล้ว: stackoverflow.com/questions/299659/ ...... มันมีวิธีแก้ปัญหาสำหรับล้างข้อมูลอ้างอิงหน่วยความจำ 'ทันเวลา' ก่อน OOM SoftReferences อาจเป็นเครื่องมือที่ช่วยแก้ปัญหาที่แท้จริงของคุณ
Steve Steiner

คำตอบ:


244

ในที่สุดคุณก็จะมีฮีปสูงสุดให้ใช้ไม่ว่าคุณจะใช้งานแพลตฟอร์มใด ใน Windows 32 บิตนี่เป็นเรื่องรอบตัว2GB (ไม่ใช่ฮีปโดยเฉพาะ แต่จำนวนหน่วยความจำทั้งหมดต่อกระบวนการ) มันเพิ่งเกิดขึ้นที่ Java เลือกที่จะทำให้ค่าเริ่มต้นเล็กลง (สมมุติว่าโปรแกรมเมอร์ไม่สามารถสร้างโปรแกรมที่มีการจัดสรรหน่วยความจำแบบไม่ต้องใช้โดยไม่ประสบปัญหานี้และต้องตรวจสอบสิ่งที่พวกเขากำลังทำอยู่)

ดังนั้นสิ่งนี้จึงมีหลายวิธีที่คุณสามารถทำได้เพื่อกำหนดจำนวนหน่วยความจำที่คุณต้องการหรือเพื่อลดจำนวนหน่วยความจำที่คุณใช้ ข้อผิดพลาดทั่วไปอย่างหนึ่งกับภาษาที่รวบรวมขยะเช่น Java หรือ C # คือการอ้างอิงรอบ ๆ วัตถุที่คุณไม่ได้ใช้งานอยู่หรือจัดสรรวัตถุจำนวนมากเมื่อคุณสามารถนำกลับมาใช้ใหม่ได้ ตราบใดที่วัตถุมีการอ้างอิงถึงวัตถุเหล่านั้นพวกเขาจะยังคงใช้พื้นที่ฮีปต่อไปเนื่องจากตัวรวบรวมขยะจะไม่ลบทิ้ง

ในกรณีนี้คุณสามารถใช้ Profiler หน่วยความจำ Java เพื่อกำหนดว่าวิธีใดในโปรแกรมของคุณที่จะจัดสรรวัตถุจำนวนมากแล้วพิจารณาว่ามีวิธีที่จะทำให้แน่ใจว่าพวกเขาจะไม่ถูกอ้างอิงอีกต่อไปหรือจะไม่จัดสรรในตอนแรก ทางเลือกหนึ่งที่ผมได้ใช้ในอดีตคือ "เจเอ็มพี" http://www.khelekore.org/jmp/

หากคุณพิจารณาว่าคุณกำลังจัดสรรออบเจ็กต์เหล่านี้ด้วยเหตุผลและคุณจำเป็นต้องเก็บรักษาข้อมูลอ้างอิง (ขึ้นอยู่กับสิ่งที่คุณทำสิ่งนี้อาจเป็นกรณีนี้) คุณจะต้องเพิ่มขนาดฮีปสูงสุดเมื่อคุณเริ่มโปรแกรม อย่างไรก็ตามเมื่อคุณทำโปรไฟล์หน่วยความจำและเข้าใจวิธีการจัดสรรวัตถุของคุณคุณควรมีความคิดที่ดีเกี่ยวกับจำนวนหน่วยความจำที่คุณต้องการ

โดยทั่วไปหากคุณไม่สามารถรับประกันได้ว่าโปรแกรมของคุณจะทำงานในจำนวน จำกัด ของหน่วยความจำ (อาจขึ้นอยู่กับขนาดอินพุต) คุณจะพบปัญหานี้เสมอ หลังจากหมดทั้งหมดนี้คุณจะต้องมองไปที่วัตถุแคชออกไปยังดิสก์ ฯลฯ ณ จุดนี้คุณควรมีเหตุผลที่ดีที่จะพูดว่า "ฉันต้องการหน่วยความจำ Xgb" สำหรับบางสิ่งและคุณไม่สามารถแก้ไขได้โดยการปรับปรุง อัลกอริทึมหรือรูปแบบการจัดสรรหน่วยความจำของคุณ โดยทั่วไปจะเป็นกรณีสำหรับอัลกอริทึมที่ทำงานบนชุดข้อมูลขนาดใหญ่ (เช่นฐานข้อมูลหรือโปรแกรมการวิเคราะห์ทางวิทยาศาสตร์) จากนั้นเทคนิคเช่นแคชและหน่วยความจำที่แมป IO มีประโยชน์


6
OpenJDK และ OracleJDK ได้รวม profiler - jvisualvm หากคุณต้องการความสะดวกสบายมากขึ้นฉันขอแนะนำ Yourkit เชิงพาณิชย์
Petr Gladkikh

121

รัน Java ด้วยตัวเลือกบรรทัดคำสั่ง-Xmxซึ่งกำหนดขนาดสูงสุดของฮีป

ดูที่นี่สำหรับรายละเอียด


3
จะตั้งค่าพารามิเตอร์นี้ได้อย่างไร? เพราะฉันใช้คำสั่ง 'gradlew assemble'
Dr.jacky

2
Run-> Run Configurations-> คลิกที่อาร์กิวเมนต์ -> ภายในประเภทอาร์กิวเมนต์ VM -Xms1g -Xmx2g
Arayan Singh

2
นั่นคือคำตอบที่แท้จริง
nccc

85

คุณสามารถระบุแต่ละโครงการว่าต้องการพื้นที่กองมากเท่าใด

ต่อไปนี้สำหรับEclipse Helios / Juno / Kepler :

คลิกเมาส์ขวาบน

 Run As - Run Configuration - Arguments - Vm Arguments, 

จากนั้นเพิ่มสิ่งนี้

-Xmx2048m

1
สวัสดี bighostkim และ cuongHuyTo ที่ไหน "อาร์กิวเมนต์" .. ฉันสามารถดูได้สูงสุดเรียกใช้การกำหนดค่า กรุณาโทรหาฉัน ฉันต้องการดาวน์โหลดและเก็บเกือบ 2,000 รายชื่อจาก gmail มันล้มเหลวเนื่องจากข้อยกเว้นหน่วยความจำหมด
AndroidRaji

@AndroiRaji: คุณคลิกขวาที่เมาส์บนคลาส Java ที่มี main ที่รันได้ (นั่นคือ "public void main (String [] args)") จากนั้นเลือก Run As - Run Configuration จากนั้น "อาร์กิวเมนต์" คือแท็บถัดจากหลัก (คุณจะเห็นแท็บหลัก, อาร์กิวเมนต์, JRE, Classpath, แหล่งที่มา, สภาพแวดล้อม, ทั่วไป)
CuongHuy ถึง

47

การเพิ่มขนาดฮีปไม่ใช่ "แก้ไข" มันเป็น "พลาสเตอร์" ชั่วคราว 100% มันจะพังอีกครั้งในที่อื่น เพื่อหลีกเลี่ยงปัญหาเหล่านี้ให้เขียนโค้ดประสิทธิภาพสูง

  1. ใช้ตัวแปรท้องถิ่นทุกที่ที่ทำได้
  2. ตรวจสอบให้แน่ใจว่าคุณเลือกวัตถุที่ถูกต้อง (EX: การเลือกระหว่าง String, StringBuffer และ StringBuilder)
  3. ใช้ระบบโค้ดที่ดีสำหรับโปรแกรมของคุณ (เช่นการใช้ตัวแปรสแตติก VS ตัวแปรที่ไม่ใช่สแตติก)
  4. สิ่งอื่น ๆ ที่สามารถทำงานกับรหัสของคุณ
  5. พยายามเคลื่อนย้ายด้วยมัลติเธรด

นี่เป็นเรื่องจริง ฉันกำลังพยายามแก้ไขปัญหาหนึ่งที่ฉันได้รับ OOM บนเธรด AWT แต่ถ้าฉันใช้เธรดใหม่ที่แตกต่างกันฉันไม่ได้รับปัญหา OOM ทั้งหมดที่ฉันสามารถค้นหาออนไลน์คือเพิ่มขนาดฮีปสำหรับเธรด AWT
Ashish

@Ash: ใช่แก้ไขปัญหาหลักแทนที่จะมองหาพลาสเตอร์
น้ำมะนาว

คอลเลกชันขยะและแนวทางการจัดการหน่วยความจำใน Java ควรแก้ไข malloc-dealloc ทั้งหมดของรุ่นก่อน :( แน่นอนฉันเห็นด้วยกับคำตอบนี้เป็นเพียงความอัปยศที่ค่าเริ่มต้นไม่ได้ทำให้ง่ายต่อการเขียนโค้ดด้วยข้อมูลแบบลีน - โครงสร้างที่ทำความสะอาดโดยเร็ว
Davos

31

คำเตือนใหญ่ที่สำนักงานของฉันเราพบว่า (บนเครื่อง windows บางเครื่อง) เราไม่สามารถจัดสรรฮีป Java ได้มากกว่า 512m สิ่งนี้กลายเป็นว่าเกิดจากผลิตภัณฑ์ต่อต้านไวรัสของ Kaspersky ที่ติดตั้งในเครื่องเหล่านั้นบางเครื่อง หลังจากถอนการติดตั้งผลิตภัณฑ์ AV เราพบว่าเราสามารถจัดสรรได้อย่างน้อย 1.6gb เช่น -Xmx1600m(m เป็นข้อบังคับและอื่น ๆ ที่ชาญฉลาดมันจะนำไปสู่ข้อผิดพลาดอื่น "ฮีปเริ่มต้นเล็กเกินไป") ทำงาน

ไม่มีความคิดว่าสิ่งนี้เกิดขึ้นกับผลิตภัณฑ์ AV อื่น ๆ แต่น่าจะเกิดขึ้นเพราะโปรแกรม AV กำลังสำรองหน่วยความจำขนาดเล็กในทุกพื้นที่ที่อยู่ดังนั้นการป้องกันการจัดสรรขนาดใหญ่เพียงครั้งเดียว


22

อาร์กิวเมนต์ VM ใช้ได้สำหรับฉันใน eclipse หากคุณกำลังใช้ eclipse เวอร์ชัน 3.4 ให้ทำดังต่อไปนี้

ไปRun --> Run Configurations -->แล้วเลือกโครงการภายใต้ Maven สร้าง -> แล้วเลือกแท็บ "JRE" -> -Xmx1024mแล้วป้อน

หรือคุณสามารถRun --> Run Configurations --> select the "JRE" tab -->ป้อน -Xmx1024m

สิ่งนี้จะเพิ่มฮีปหน่วยความจำสำหรับบิลด์ / โปรเจ็กต์ทั้งหมด ขนาดหน่วยความจำด้านบนคือ 1 GB คุณสามารถเพิ่มประสิทธิภาพตามที่คุณต้องการ


18

ใช่-Xmxคุณสามารถกำหนดค่าหน่วยความจำเพิ่มเติมสำหรับ JVM ของคุณได้ เพื่อให้แน่ใจว่าคุณจะไม่รั่วไหลหรือเสียความทรงจำ ใช้ดัมพ์ฮีปและใช้Eclipse Memory Analyzerเพื่อวิเคราะห์ปริมาณการใช้หน่วยความจำของคุณ


JVMJ9VM007E ตัวเลือกบรรทัดคำสั่งที่ไม่รู้จัก: -Xmx ไม่สามารถสร้างเครื่องเสมือน Java Downvote
Philip Rego

17

ฉันต้องการที่จะเพิ่มคำแนะนำจาก oracle ปัญหาในการถ่ายภาพบทความ

ข้อยกเว้นในเธรด thread_name: java.lang.OutOfMemoryError: พื้นที่ฮีพของ Java

ข้อความรายละเอียดพื้นที่ Java heap บ่งชี้ว่าไม่สามารถจัดสรรวัตถุใน Java heap ข้อผิดพลาดนี้ไม่ได้แปลว่าหน่วยความจำรั่ว

สาเหตุที่เป็นไปได้:

  1. ปัญหาการกำหนดค่าอย่างง่ายที่ขนาดฮีปที่ระบุไม่เพียงพอสำหรับแอปพลิเคชัน

  2. แอปพลิเคชันถือการอ้างอิงไปยังวัตถุโดยไม่ได้ตั้งใจและเป็นการป้องกันไม่ให้วัตถุถูกรวบรวมขยะ

  3. การใช้งานที่มากเกินไปของ finalizers

แหล่งที่มาที่เป็นไปได้อื่น ๆ ของข้อผิดพลาดนี้เกิดขึ้นกับแอปพลิเคชันที่ใช้ประโยชน์จาก Finalizers มากเกินไป หากคลาสมีเมธอดการสรุปดังนั้นอ็อบเจ็กต์ชนิดนั้นจะไม่มีการเรียกคืนพื้นที่ในเวลารวบรวมขยะ

หลังจากการรวบรวมขยะวัตถุจะเข้าคิวเพื่อการสรุปซึ่งจะเกิดขึ้นในภายหลัง finalizersถูกเรียกใช้งานโดยเธรด daemon ที่ให้บริการคิวการทำ finalization หากรอบสุดท้ายเธรดไม่สามารถติดตามคิวการสรุปได้ดังนั้นฮีป Java สามารถเติมได้และข้อยกเว้นOutOfMemoryErrorประเภทนี้จะถูกโยนทิ้ง

สถานการณ์สมมติหนึ่งที่อาจทำให้สถานการณ์นี้เกิดขึ้นเมื่อแอปพลิเคชันสร้างเธรดที่มีลำดับความสำคัญสูงซึ่งทำให้คิวการสรุปสุดท้ายเพิ่มขึ้นในอัตราที่เร็วกว่าอัตราที่เธรด finalizer กำลังให้บริการคิวนั้น


9

ทำตามขั้นตอนด้านล่าง:

  1. เปิด catalina.shจาก tomcat / bin

  2. เปลี่ยน JAVA_OPTS เป็น

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
  3. รีสตาร์ท Tomcat ของคุณ


8

ฉันอ่านที่อื่นที่คุณสามารถลอง - catch java.lang.OutOfMemoryError และใน catch block คุณสามารถเพิ่มทรัพยากรทั้งหมดที่คุณรู้ว่าอาจใช้หน่วยความจำจำนวนมากปิดการเชื่อมต่อและอื่น ๆ จากนั้นทำ System.gc()นั้นลองอีกครั้ง คุณกำลังจะทำ

อีกวิธีคือแม้ว่าฉันไม่ทราบว่าจะทำงานได้ แต่ฉันกำลังทดสอบว่าจะทำงานในใบสมัครของฉัน

แนวคิดคือการรวบรวมขยะโดยเรียก System.gc () ซึ่งเป็นที่รู้จักกันในการเพิ่มหน่วยความจำว่าง คุณสามารถตรวจสอบเรื่องนี้ได้หลังจากประมวลผลการกลืนรหัสความจำ

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();

6
โดยทั่วไปฉันคิดว่า JVM จะชอบ Garbage Collect (GC) มากกว่าที่จะโยน OutOfMemoryError การเรียก System.gc () อย่างชัดเจนหลังจาก OutOfMemoryError อาจช่วย VMs / การกำหนดค่าบางอย่าง แต่ฉันไม่คิดว่ามันจะทำงานได้ดีในกรณีทั่วไป อย่างไรก็ตามการทิ้งการอ้างอิงวัตถุที่ไม่จำเป็นนั้นจะช่วยได้อย่างแน่นอนในเกือบทุกกรณี
Mike Clark

6
@mwangi Systeming Call.gc () โดยตรงจากรหัสนั้นเป็นความคิดที่ไม่ดี เป็นเพียงข้อเสนอแนะสำหรับ JVM ที่ GC ควรดำเนินการ แต่ไม่มีการรับประกันว่าจะมีการดำเนินการอย่างแน่นอน

7

วิธีง่ายๆในการแก้ปัญหาOutOfMemoryErrorในจาวาคือการเพิ่มขนาดฮีพสูงสุดโดยใช้ตัวเลือก JVM -Xmx512Mสิ่งนี้จะแก้ไข OutOfMemoryError ของคุณได้ทันที นี่เป็นทางออกที่ฉันต้องการเมื่อฉันได้รับ OutOfMemoryError ใน Eclipse, Maven หรือ ANT ในขณะที่สร้างโครงการเพราะตามขนาดของโครงการที่คุณสามารถเรียกใช้หน่วยความจำได้อย่างง่ายดาย

นี่คือตัวอย่างของการเพิ่มขนาดฮีพสูงสุดของ JVM นอกจากนี้ยังควรเก็บปันส่วน -Xmx เป็น -Xms ทั้ง 1: 1 หรือ 1: 1.5 หากคุณตั้งค่าขนาดฮีพในแอ็พพลิเคชัน Java ของคุณ

export JVM_ARGS="-Xms1024m -Xmx1024m"

ลิงค์อ้างอิง


1
มีความคิดอะไรบ้างที่เราจำเป็นต้องเก็บไว้ในอัตราส่วน 1: 1 หรือ 1: 1.5
ernesto

7

โดยค่าเริ่มต้นสำหรับการพัฒนา JVM ใช้ขนาดเล็กและกำหนดค่าขนาดเล็กสำหรับคุณสมบัติอื่น ๆ ที่เกี่ยวข้องกับประสิทธิภาพ แต่สำหรับการผลิตคุณสามารถปรับแต่งเช่น (นอกจากนี้ยังสามารถกำหนดค่าเฉพาะ Application Server ได้) -> (หากยังมีหน่วยความจำไม่เพียงพอที่จะตอบสนองคำขอและฮีปมีขนาดสูงสุดแล้ว OutOfMemoryError จะเกิดขึ้น)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

ตัวอย่างเช่น: บนแพลตฟอร์ม linux สำหรับการตั้งค่าโหมดการผลิตที่ดีกว่า

หลังจากดาวน์โหลดและกำหนดค่าเซิร์ฟเวอร์ด้วยวิธีนี้http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/ด้วยวิธีนี้

1. สร้างไฟล์ setenv.sh ในโฟลเดอร์ / opt / tomcat / bin /

   touch /opt/tomcat/bin/setenv.sh

2. เปิดและเขียนพารามิเตอร์นี้เพื่อตั้งโหมดที่ต้องการ

nano  /opt/tomcat/bin/setenv.sh 

export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3service tomcat restart

โปรดทราบว่า JVM ใช้หน่วยความจำมากกว่าฮีป ตัวอย่างเช่นวิธี Java, สแต็กของเธรดและตัวจัดการเนทิฟถูกจัดสรรในหน่วยความจำแยกจากฮีปรวมถึงโครงสร้างข้อมูลภายใน JVM


7

ฉันประสบปัญหาเดียวกันจากขนาดจาวาฮีป

ฉันมีสองวิธีถ้าคุณใช้ java 5 (1.5)

  1. เพียงติดตั้ง jdk1.6 และไปที่การตั้งค่าของ eclipse และตั้งค่าเส้นทาง jre ของ jav1 1.6 ตามที่คุณติดตั้ง

  2. ตรวจสอบอาร์กิวเมนต์ VM ของคุณและปล่อยให้เป็นอย่างที่มันเป็น เพียงเพิ่มหนึ่งบรรทัดด้านล่างของอาร์กิวเมนต์ทั้งหมดที่มีอยู่ในอาร์กิวเมนต์ VM เป็น -Xms512m -Xmx512m -XX: MaxPermSize = ... m (192m)

ฉันคิดว่ามันจะทำงาน ...


7

หากคุณต้องการตรวจสอบการใช้งานหน่วยความจำของคุณที่รันไทม์java.lang.managementแพ็คเกจที่เสนอMBeansที่สามารถใช้ในการตรวจสอบพูลหน่วยความจำใน VM ของคุณ (เช่นพื้นที่ eden การสร้างอายุที่เก็บ ฯลฯ ) และพฤติกรรมการรวบรวมขยะ

พื้นที่ฮีปฟรีที่รายงานโดย MBeans เหล่านี้จะแตกต่างกันมากขึ้นอยู่กับพฤติกรรมของ GC โดยเฉพาะอย่างยิ่งหากแอปพลิเคชันของคุณสร้างวัตถุจำนวนมากซึ่งภายหลัง GC-ed วิธีหนึ่งที่เป็นไปได้คือการตรวจสอบพื้นที่ว่างฮีปหลังจากแต่ละ GC แบบเต็มซึ่งคุณอาจใช้เพื่อตัดสินใจในการเพิ่มหน่วยความจำด้วยวัตถุที่ยังคงอยู่

ท้ายที่สุดทางออกที่ดีที่สุดของคุณคือ จำกัด การเก็บรักษาหน่วยความจำเท่าที่จะทำได้ในขณะที่ประสิทธิภาพยังคงเป็นที่ยอมรับ ตามที่ระบุไว้ก่อนหน้านี้หน่วยความจำจะถูก จำกัด อยู่เสมอ แต่แอปของคุณควรมีกลยุทธ์ในการจัดการกับความจำที่หมดไป


5

โปรดทราบว่าหากคุณต้องการสิ่งนี้ในสถานการณ์การปรับใช้ให้พิจารณาใช้ Java WebStart (ด้วยรุ่น "ondisk" ไม่ใช่เครือข่ายเดียว - เป็นไปได้ใน Java 6u10 และใหม่กว่า) เนื่องจากอนุญาตให้คุณระบุอาร์กิวเมนต์ต่างๆกับ JVM ในการไขว้ ทางแพลตฟอร์ม

มิฉะนั้นคุณจะต้องมีตัวเรียกใช้งานระบบปฏิบัติการที่กำหนดอาร์กิวเมนต์ที่คุณต้องการ


Java WebStart กำลังถูกยกเลิก ฉันยังไม่ทราบถึงการทดแทนที่เหมาะสม
Thorbjørn Ravn Andersen

1

หากปัญหานี้เกิดขึ้นใน Wildfly 8 และ JDK1.8 เราต้องระบุการตั้งค่า MaxMetaSpace แทนการตั้งค่า PermGen

ตัวอย่างเช่นเราจำเป็นต้องเพิ่มการกำหนดค่าด้านล่างในไฟล์ setenv.sh ของ wildfly JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

สำหรับข้อมูลเพิ่มเติมโปรดตรวจสอบWildfly Heap Issue


1

สำหรับ netbeans คุณสามารถกำหนดขนาด heap สูงสุดเพื่อแก้ปัญหาได้

ไปที่ 'เรียกใช้' จากนั้น -> 'ตั้งค่าการกำหนดค่าโครงการ' -> 'ปรับแต่ง' -> 'เรียกใช้' ของหน้าต่างที่เปิดขึ้นมา -> 'ตัวเลือก VM' -> กรอก '-Xms2048m -Xmx2048m' .


1

หากคุณยังคงจัดสรรและรักษาการอ้างอิงไปยังวัตถุคุณจะเติมหน่วยความจำจำนวนเท่าใดก็ได้ที่คุณมี

ทางเลือกหนึ่งคือปิดและเปิดไฟล์โปร่งใสเมื่อสลับแท็บ (คุณเก็บตัวชี้ไปที่ไฟล์และเมื่อผู้ใช้สลับแท็บคุณปิด & ล้างวัตถุทั้งหมด ... มันจะทำให้การเปลี่ยนแปลงของไฟล์ช้าลง ... แต่ ... ) และอาจเก็บเพียง 3 หรือ 4 ไฟล์ในหน่วยความจำ

สิ่งอื่นที่คุณควรทำคือเมื่อผู้ใช้เปิดไฟล์โหลดและสกัด OutOfMemoryError ใด ๆ จากนั้น (เนื่องจากไม่สามารถเปิดไฟล์ได้) ให้ปิดไฟล์นั้นทำความสะอาดวัตถุและเตือนผู้ใช้ว่าควรปิดสิ่งที่ไม่ได้ใช้ ไฟล์

ความคิดของคุณเกี่ยวกับการขยายหน่วยความจำเสมือนแบบไดนามิกไม่ได้ช่วยแก้ปัญหาเพราะเครื่องมีทรัพยากร จำกัด ดังนั้นคุณควรระมัดระวังและจัดการกับปัญหาหน่วยความจำ (หรืออย่างน้อยต้องระวังด้วย)

คู่ของคำแนะนำที่ฉันเคยเห็นด้วยการรั่วไหลของหน่วยความจำคือ:

-> จำไว้ว่าถ้าคุณใส่อะไรลงไปในคอลเลคชั่นและหลังจากนั้นก็ลืมมันไปคุณยังมีการอ้างอิงที่ดีดังนั้นลบล้างคอลเล็กชั่นทำความสะอาดมันหรือทำอะไรกับมัน ... ถ้าไม่คุณจะพบ หน่วยความจำรั่วยากที่จะหา

-> บางทีการใช้คอลเล็กชันที่มีการอ้างอิงที่ไม่รัดกุม (weakhashmap ... ) สามารถช่วยแก้ปัญหาหน่วยความจำได้ แต่คุณต้องระวังด้วยเพราะคุณอาจพบว่ามีการรวบรวมวัตถุที่คุณค้นหา

-> ความคิดอื่นที่ฉันได้พบคือการพัฒนาคอลเลกชันถาวรที่เก็บไว้ในวัตถุฐานข้อมูลที่ใช้น้อยที่สุดและโหลดอย่างโปร่งใส นี่อาจเป็นวิธีที่ดีที่สุด ...


0

หากทุกอย่างอื่นล้มเหลวนอกเหนือจากการเพิ่มขนาดฮีพสูงสุดให้ลองเพิ่มขนาดการสลับ สำหรับ Linux ณ ตอนนี้สามารถดูคำแนะนำที่เกี่ยวข้องได้ในhttps://linuxize.com/post/create-a-linux-swap-file/ https://linuxize.com/post/create-a-linux-swap-file/

วิธีนี้จะช่วยได้หากคุณกำลังรวบรวมบางสิ่งที่ยิ่งใหญ่ในแพลตฟอร์มแบบฝัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.