ขนาดฮีพ Java สูงสุดของ JVM 32 บิตบนระบบปฏิบัติการ 64 บิต


107

คำถามไม่ได้เกี่ยวกับขนาดฮีปสูงสุดบนระบบปฏิบัติการ 32 บิตเนื่องจากระบบปฏิบัติการ 32 บิตมีขนาดหน่วยความจำสูงสุดที่แอดเดรสได้ 4GB และขนาดฮีปสูงสุดของ JVM นั้นขึ้นอยู่กับจำนวนหน่วยความจำว่างที่ต่อเนื่องกันสามารถจองได้

ฉันสนใจที่จะทราบขนาดฮีปสูงสุด (ทั้งในทางทฤษฎีและในทางปฏิบัติ) สำหรับ JVM 32 บิตที่ทำงานในระบบปฏิบัติการ 64 บิต โดยทั่วไปฉันกำลังมองหาที่คำตอบคล้ายกับตัวเลขในคำถามที่เกี่ยวข้องในดังนั้น

เหตุใดจึงใช้ JVM 32 บิตแทน 64 บิตเหตุผลนั้นไม่ใช่ทางเทคนิค แต่เป็นการบริหาร / ระบบราชการ - อาจสายเกินไปที่จะติดตั้ง JVM 64 บิตในสภาพแวดล้อมการใช้งานจริง

คำตอบ:


70

JVM แบบ 32 บิตซึ่งคาดว่าจะมีหน่วยความจำขนาดใหญ่เพียงชิ้นเดียวและการใช้พอยน์เตอร์ดิบไม่สามารถใช้มากกว่า 4 Gb (เนื่องจากเป็นขีด จำกัด 32 บิตซึ่งใช้กับพอยน์เตอร์ด้วย) ซึ่งรวมถึง Sun และ - ฉันค่อนข้างแน่ใจ - รวมถึงการนำ IBM ไปใช้ด้วย ฉันไม่รู้ว่าเช่น JRockit หรืออื่น ๆ มีตัวเลือกหน่วยความจำขนาดใหญ่พร้อมการใช้งาน 32 บิตหรือไม่

หากคุณคาดว่าจะถึงขีด จำกัด นี้คุณควรพิจารณาอย่างยิ่งที่จะเริ่มต้นแทร็กคู่ขนานเพื่อตรวจสอบความถูกต้องของ JVM 64 บิตสำหรับสภาพแวดล้อมการผลิตของคุณเพื่อให้คุณพร้อมสำหรับเมื่อสภาพแวดล้อม 32 บิตหยุดทำงาน มิฉะนั้นคุณจะต้องทำงานนั้นภายใต้ความกดดันซึ่งไม่ดีเลย


แก้ไข 2014-05-15: คำถามที่พบบ่อยของ Oracle:

ขีด จำกัด ฮีปทางทฤษฎีสูงสุดสำหรับ JVM 32 บิตคือ 4G เนื่องจากข้อ จำกัด เพิ่มเติมต่างๆเช่นการแลกเปลี่ยนที่พร้อมใช้งานการใช้พื้นที่แอดเดรสเคอร์เนลการกระจายตัวของหน่วยความจำและค่าใช้จ่าย VM ในทางปฏิบัติขีด จำกัด อาจต่ำกว่านี้มาก ในระบบ Windows 32 บิตที่ทันสมัยส่วนใหญ่ขนาดฮีปสูงสุดจะอยู่ในช่วง 1.4G ถึง 1.6G บนเมล็ด Solaris 32 บิตพื้นที่แอดเดรสถูก จำกัด ไว้ที่ 2G บนระบบปฏิบัติการ 64 บิตที่รัน VM 32 บิตขนาดฮีปสูงสุดอาจสูงกว่าโดยเข้าใกล้ 4G ในระบบ Solaris จำนวนมาก

( http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit )


ไม่มีความกดดันในการทำงานที่นี่ ฉันรู้ว่าควรติดตั้ง JVM 64 บิตตั้งแต่แรก แต่มันทำให้ฉันคิดว่า JVM แบบ 32 บิตจะทำงานในสภาพแวดล้อมที่มีทรัพยากรมากขึ้นได้อย่างไร
Vineet Reynolds

1
มันไม่ได้อยู่ที่ประมาณ 2GB เนื่องจากการลงนาม? หรือว่าเป็นเพียง Sun JVM?
Sebastian Ganslandt

9
ตัวชี้ไม่ได้ลงนาม - ไม่สมเหตุสมผลที่จะพูดถึงตำแหน่งหน่วยความจำเชิงลบ
Thorbjørn Ravn Andersen

12
ไม่มันไม่ใช่ 2GB เนื่องจากการลงนาม อย่างไรก็ตามส่วนหนึ่งของพื้นที่แอดเดรส 4GB สงวนไว้สำหรับเคอร์เนล OS ใน Windows เวอร์ชันสำหรับผู้บริโภคทั่วไปขีด จำกัด คือ 2GB บน Linux และ Windows เวอร์ชันเซิร์ฟเวอร์ (32 บิต) ขีด จำกัด คือ 3GB ต่อกระบวนการ
Jesper

3
@Jesper ฉันสงสัยว่า JVM 32 บิตที่ทำงานบนระบบปฏิบัติการ 64 บิตอาจมีพื้นที่แอดเดรสเต็ม 4 GB หรือไม่?
Thorbjørn Ravn Andersen

90

คุณสามารถถาม Java Runtime:

public class MaxMemory {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        long totalMem = rt.totalMemory();
        long maxMem = rt.maxMemory();
        long freeMem = rt.freeMemory();
        double megs = 1048576.0;

        System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
        System.out.println ("Max Memory:   " + maxMem + " (" + (maxMem/megs) + " MiB)");
        System.out.println ("Free Memory:  " + freeMem + " (" + (freeMem/megs) + " MiB)");
    }
}

ซึ่งจะรายงาน "หน่วยความจำสูงสุด" ตามการจัดสรรฮีปเริ่มต้น ดังนั้นคุณยังคงต้องเล่นด้วย-Xmx (บนHotSpot ) ฉันพบว่าการทำงานบน Windows 7 Enterprise 64 บิต HotSpot JVM 32 บิตของฉันสามารถจัดสรรได้ถึง 1577MiB:

[C: scratch]> java -Xmx1600M MaxMemory
เกิดข้อผิดพลาดระหว่างการเริ่มต้น VM
ไม่สามารถจองพื้นที่เพียงพอสำหรับฮีปวัตถุ
ไม่สามารถสร้างเครื่องเสมือน Java
[C: scratch]> java -Xmx1590M MaxMemory
หน่วยความจำทั้งหมด: 2031616 (1.9375 MiB)
หน่วยความจำสูงสุด: 1654456320 (1577.8125 MiB)
หน่วยความจำว่าง: 1840872 (1.75559234619 MiB)
[C: scratch]>

ในขณะที่JVM 64 บิตบนระบบปฏิบัติการเดียวกันแน่นอนว่ามันสูงกว่ามาก (ประมาณ 3TiB)

[C: scratch]> java -Xmx3560G MaxMemory
เกิดข้อผิดพลาดระหว่างการเริ่มต้น VM
ไม่สามารถจองพื้นที่เพียงพอสำหรับฮีปวัตถุ
[C: scratch]> java -Xmx3550G MaxMemory
หน่วยความจำทั้งหมด: 94240768 (89.875 MiB)
หน่วยความจำสูงสุด: 3388252028928 (3184151.84297 MiB)
หน่วยความจำว่าง: 93747752 (89.4048233032 MiB)
[C: scratch]>

ดังที่คนอื่น ๆ ได้กล่าวไปแล้วขึ้นอยู่กับระบบปฏิบัติการ

  • สำหรับ Windows 32 บิต: จะเป็น <2GB ( หนังสือภายในของ Windowsระบุว่า 2GB สำหรับกระบวนการของผู้ใช้)
  • สำหรับ BSD / Linux 32 บิต: <3GB (จาก Devil Book)
  • สำหรับ 32-bit MacOS X: <4GB (จากหนังสือภายในของ MacOS X )
  • ไม่แน่ใจเกี่ยวกับ Solaris 32 บิตลองใช้รหัสด้านบนและแจ้งให้เราทราบ

สำหรับโฮสต์ OS 64 บิตหาก JVM เป็น 32 บิตก็จะยังคงขึ้นอยู่ซึ่งส่วนใหญ่จะเป็นไปตามที่แสดงไว้ข้างต้น

- อัพเดท 20110905 : ฉันแค่อยากจะชี้ให้เห็นข้อสังเกต / รายละเอียดอื่น ๆ :

  • ฮาร์ดแวร์ที่ฉันใช้งานนี้เป็นแบบ 64 บิตพร้อมติดตั้ง RAM จริง 6GB ระบบปฏิบัติการคือ Windows 7 Enterprise 64 บิต
  • จำนวนเงินที่แท้จริงของการRuntime.MaxMemoryที่สามารถได้รับการจัดสรรยังขึ้นอยู่กับระบบปฏิบัติการของชุดทำงาน ฉันเคยวิ่งสิ่งนี้ในขณะที่ฉันใช้ VirtualBox และพบว่าฉันไม่สามารถเริ่ม HotSpot JVM ได้สำเร็จ-Xmx1590Mและต้องมีขนาดเล็กลง นอกจากนี้ยังบอกเป็นนัยว่าคุณอาจได้รับมากกว่า 1590M ขึ้นอยู่กับขนาดชุดการทำงานของคุณในขณะนั้น (แม้ว่าฉันจะยังคงรักษาไว้ให้ต่ำกว่า 2GiB สำหรับ 32 บิตเนื่องจากการออกแบบของ Windows)

13
ฉันชอบที่คุณทดสอบจริงๆมากกว่าที่จะเดา
Jim Hurne

3
@djangofan อยู่พอดีเลย โปรแกรมควรหารด้วย 1,048,576 (1024 * 1024 หรือ 2 ^ 20) ไม่ใช่ 104,856 แต่นั่นเป็นเพียงสิ่งที่แสดง ดังที่คุณเห็นจากคำสั่งเขาพยายามตั้งค่าขนาดฮีปสูงสุดเป็น 1,590 MiB เท่านั้น
Jim Hurne

1
คำตอบที่เย็นมาก (ผมอยากจะบอกคำตอบ) กับตัวอย่างรหัสและรายละเอียดที่ครอบคลุมระบบปฏิบัติการทั้งหมด
TGP1994

3
ติดตามความคิดเห็นก่อนหน้าของฉัน: jdocs (สำหรับ windows atleast) ระบุว่าพารามิเตอร์ -Xmx และ -Xms ต้องได้รับค่าที่เป็นผลคูณ 1024 ... ฉันไม่แน่ใจว่าเป็น 1590 หรือไม่ดังนั้นฉันจึงคิดว่าแปลก ควรคาดหวังผลลัพธ์
TGP1994

4
เห็นดี TGP1994 ฉันคิดว่าเพราะฉันได้ระบุทวีคูณ 'M' และ 'G' แล้วขนาด (เป็นไบต์) ก็จะเป็นจำนวน 1024 ไบต์อยู่ดี เช่น 1590M จะถูกแยกวิเคราะห์เป็น 1590 * (1024 * 1024) = 1667235840 ไบต์ (1628160KiB - จำนวนคู่ของ 1024 แน่นอน)
ไมค์

16

คุณไม่ได้ระบุที่ OS

ภายใต้ Windows (สำหรับแอปพลิเคชันของฉัน - แอปพลิเคชันการจัดการความเสี่ยงที่ใช้งานมานาน) เราสังเกตเห็นว่าเราสามารถไปได้ไม่เกิน 1280MB บน Windows 32 บิต ฉันสงสัยว่าการใช้ JVM 32 บิตที่ต่ำกว่า 64 บิตจะสร้างความแตกต่างได้

เราย้ายแอปไปยัง Linux และเราใช้งาน JVM 32 บิตบนฮาร์ดแวร์ 64 บิตและมี VM 2.2GB ที่ทำงานได้ค่อนข้างง่าย

ปัญหาใหญ่ที่สุดที่คุณอาจพบคือ GC ขึ้นอยู่กับสิ่งที่คุณใช้หน่วยความจำ


ฉันอยากทราบข้อ จำกัด ของ Solaris 10 แต่นั่นก็เป็นเพียงปัญหาของฉันเท่านั้น อยากทราบ OS อื่นด้วยเผื่อวันฝนตก :)
Vineet Reynolds

ไม่แน่ใจเกี่ยวกับ Solaris ฉันคาดว่าขนาด VM จะค่อนข้างใหญ่ประสบการณ์ Java บน Solaris ของฉันมาจากไม่กี่ปีที่ผ่านมา และการเป็น Sun VM บน Sun OS บนฮาร์ดแวร์ Sun สิ่งต่าง ๆ ก็ทำงานได้ดี ฉันยังเชื่อว่ามีปัญหา GC ภายใต้ Solaris น้อยกว่า Linux / Windows
Fortyrunner

Windows ตัวนี้คืออะไร ฉันเชื่อว่า Windows เวอร์ชันเซิร์ฟเวอร์ 32 บิตสามารถจัดการหน่วยความจำจำนวนมากได้ดีกว่ามาก
Thorbjørn Ravn Andersen

ในที่สุดก็กล่าวถึงระบบปฏิบัติการ ;-) คุณติดตั้งเคอร์เนล 64 บิตแล้วหรือยัง?
Thorbjørn Ravn Andersen

เป็นเซิร์ฟเวอร์ Win2k การย้ายไปที่ Win2k3 (สิ่งต่างๆเคลื่อนไหวช้า .. ) นั้นสายเกินไปและเราเปลี่ยนไปใช้ Linux แทน
Fortyrunner

14

จาก4.1.2 Heap Sizing :

"สำหรับโมเดลกระบวนการ 32 บิตโดยทั่วไปขนาดแอดเดรสเสมือนสูงสุดของกระบวนการคือ 4 GB แม้ว่าระบบปฏิบัติการบางระบบจะ จำกัด ไว้ที่ 2 GB หรือ 3 GB โดยทั่วไปขนาดฮีปสูงสุดคือ -Xmx3800m (1600m) สำหรับขีด จำกัด 2 GB ) แม้ว่าข้อ จำกัด ที่แท้จริงจะขึ้นอยู่กับแอปพลิเคชันสำหรับโมเดลกระบวนการ 64 บิตค่าสูงสุดจะไม่ จำกัด เป็นหลัก "

พบคำตอบที่ดีสวยนี่: หน่วยความจำสูงสุด Java บน Windows XP


12

เราเพิ่งมีประสบการณ์เกี่ยวกับเรื่องนี้ เราได้ย้ายจาก Solaris (x86-64 เวอร์ชัน 5.10) ไปยัง Linux (RedHat x86-64) เมื่อเร็ว ๆ นี้และได้ตระหนักว่าเรามีหน่วยความจำน้อยกว่าสำหรับกระบวนการ JVM 32 บิตบน Linux มากกว่า Solaris

สำหรับ Solaris จะมีขนาดเกือบ 4GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)

เรารันแอพของเราด้วย-Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512mโดยไม่มีปัญหากับ Solaris ในช่วงสองสามปีที่ผ่านมา พยายามย้ายไปที่ linux และเรามีปัญหากับข้อผิดพลาดหน่วยความจำแบบสุ่มเมื่อเริ่มต้น เราเท่านั้นที่จะได้รับมันอย่างต่อเนื่องเริ่มต้นขึ้นใน-Xms2300 -Xmx2300 จากนั้นเราได้รับคำแนะนำจากฝ่ายสนับสนุน

กระบวนการ 32 บิตบน Linux มีพื้นที่แอดเดรสแอดเดรสสูงสุด 3gb (3072mb) ในขณะที่ Solaris เป็นแบบเต็ม 4gb (4096mb)


เหตุผลของคำตอบที่ได้รับจากฝ่ายสนับสนุนอยู่ที่จำนวนหน่วยความจำที่สามารถระบุแอดเดรสได้สำหรับกระบวนการ ขึ้นอยู่กับเคอร์เนลของ Linux และแม้แต่บนฮาร์ดแวร์ ในทางทฤษฎีหน่วยความจำแอดเดรสถูก จำกัด ไว้ที่ 2 ^ 32 = 4G (และขนาดฮีป Java จะน้อยกว่านี้) แต่สิ่งนี้สามารถขยายได้ (ในทางทฤษฎี) โดยใช้ hugemem และ PAE ฉันไม่ได้ลองสิ่งนี้
Vineet Reynolds

9

ข้อ จำกัด ของ JVM 32 บิตบนระบบปฏิบัติการ 64 บิตจะเหมือนกับข้อ จำกัด ของ JVM 32 บิตบนระบบปฏิบัติการ 32 บิต ท้ายที่สุด JVM 32 บิตจะทำงานในเครื่องเสมือน 32 บิต (ในแง่การจำลองเสมือน) ดังนั้นจึงไม่รู้ว่ากำลังทำงานบนระบบปฏิบัติการ 64 บิต / เครื่อง

ข้อดีอย่างหนึ่งของการรัน JVM 32 บิตบนระบบปฏิบัติการ 64 บิตเทียบกับระบบปฏิบัติการ 32 บิตคือคุณสามารถมีหน่วยความจำกายภาพได้มากขึ้นดังนั้นจึงพบการสลับ / การแบ่งหน้าน้อยลง ข้อได้เปรียบนี้จะเกิดขึ้นจริงก็ต่อเมื่อคุณมีกระบวนการหลายอย่าง


1
อาจมีความแตกต่างเล็กน้อยขึ้นอยู่กับฮาร์ดแวร์และวิธีการจำลองเสมือน โดยทั่วไปพื้นที่แอดเดรส 4GB บางส่วนจะใช้สำหรับอุปกรณ์ที่แมปหน่วยความจำ เลเยอร์การจำลองเสมือนอาจมีหรือไม่มีรอยเท้าหน่วยความจำเหมือนกับอุปกรณ์จริงบนเครื่อง
Eric J.

8
ไม่มาก มีพื้นที่มากขึ้นสำหรับ JVM ในเครื่อง 64 บิตเนื่องจากพื้นที่แอดเดรส 32 บิตไม่จำเป็นต้องแชร์กับระบบปฏิบัติการหรืออินเทอร์เฟซฮาร์ดแวร์
Thorbjørn Ravn Andersen

นั่นเป็นความจริง แต่ทั้งหมดนั้นหมายความว่าเครื่องเสมือน 32 บิตของคุณอาจมีค่าใช้จ่ายที่แตกต่างจากเครื่อง 32 บิตจริงเล็กน้อย (แย่กว่าหรือดีกว่า) ไม่ว่าจะด้วยวิธีใดคุณกำลังเรียกใช้ JVM บนเครื่อง 32 บิต (จริงหรือเสมือน) ดังนั้นคุณจะอยู่ภายใต้ข้อ จำกัด 32 บิตมาตรฐาน นั่นคือเพดานที่แน่นอนของ 4GB
Laurence Gonsalves

Thorbjørn: ระบบปฏิบัติการและอินเทอร์เฟซฮาร์ดแวร์ยังคงต้องมีการแมปลงใน VM 32 บิต จำนวนที่แน่นอนของการได้ยินอาจแตกต่างกัน แต่จะยังคงอยู่ที่นั่น หากคุณสามารถจำลองเสมือนได้ภายใต้ระบบปฏิบัติการ 64 บิตสิ่งที่จะหยุดคุณไม่ให้จำลองเสมือนจริงภายใต้ระบบปฏิบัติการ 32 บิต? นี่คือหน่วยความจำเสมือนที่เรากำลังพูดถึง
Laurence Gonsalves

2
LG: ฉันไม่เห็นด้วยกับคำตอบเดิมของคุณ เคอร์เนลระบบปฏิบัติการและพื้นที่ที่อยู่ HW และบัสใด ๆ ที่แมปจะเคี้ยวพื้นที่ที่อยู่จำนวนมากและแม้ว่าจะไม่ได้แมปลงในโปรแกรมผู้ใช้ แต่ก็จะลดจำนวน "ที่เหลือ" หลังจากที่ระบบปฏิบัติการตั้งค่าตัวเอง นี่เป็นพื้นที่ว่าง 4GB 32 บิตจำนวนมาก ตามเนื้อผ้าหมายความว่าประมาณ 25% -75% ของ 4GB ไม่พร้อมใช้งานสำหรับกระบวนการของผู้ใช้ :-) kernel hacker
DigitalRoss

6

เหตุใดจึงใช้ JVM 32 บิตแทน 64 บิตเหตุผลนั้นไม่ใช่ทางเทคนิค แต่เป็นการบริหาร / ระบบราชการ ...

เมื่อฉันทำงานกับ BEA เราพบว่าแอปพลิเคชันทั่วไปทำงานช้าลงใน JVM 64 บิตจากนั้นก็ทำงานเมื่อทำงานใน JVM 32 บิต ในบางกรณีประสิทธิภาพการทำงานจะช้าลงถึง 25% ดังนั้นหากแอปพลิเคชันของคุณไม่ต้องการหน่วยความจำเพิ่มเติมทั้งหมดคุณควรตั้งค่าเซิร์ฟเวอร์ 32 บิตเพิ่มเติม

อย่างที่ฉันจำได้ว่าเหตุผลทางเทคนิคที่พบบ่อยที่สุดสามประการสำหรับการใช้ 64 บิตที่เจ้าหน้าที่บริการมืออาชีพของ BEA พบคือ:

  1. แอปพลิเคชั่นนี้จัดการภาพขนาดใหญ่หลายภาพ
  2. แอปพลิเคชันกำลังทำการกระทืบจำนวนมาก
  3. แอปพลิเคชั่นนี้มีหน่วยความจำรั่วลูกค้าเป็นตัวการสำคัญในสัญญาของรัฐบาลและพวกเขาไม่ต้องการใช้เวลาและค่าใช้จ่ายในการติดตามการรั่วไหลของหน่วยความจำ (การใช้ฮีปหน่วยความจำขนาดใหญ่จะเพิ่ม MTBF และไพรม์จะยังคงได้รับเงิน)

.


เป็นเรื่องดีที่คุณให้คำแนะนำโดยตรงอดีตพนักงานของ BEA :)
emecas

4

ปัจจุบัน JROCKIT JVM เป็นเจ้าของโดย Oracle สนับสนุนการใช้งานฮีปแบบไม่ต่อเนื่องกันจึงทำให้ JVM 32 บิตเข้าถึงหน่วยความจำได้มากกว่า 3.8 GB เมื่อ JVM ทำงานบน Windows OS 64 บิต (2.8 GB เมื่อทำงานบนระบบปฏิบัติการ 32 บิต)

http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows

สามารถดาวน์โหลด JVM ได้อย่างอิสระ (ต้องลงทะเบียน) ที่

http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html


4

นี่คือการทดสอบบางส่วนภายใต้ Solaris และ Linux 64 บิต

Solaris 10 - SPARC - เครื่อง T5220 พร้อม RAM 32 GB (และฟรีประมาณ 9 GB)

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3750m MaxMemory
Error occurred during initialization of VM
Could not reserve space for ObjectStartArray
$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3700m MaxMemory
Total Memory: 518520832 (494.5 MiB)
Max Memory:   3451912192 (3292.0 MiB)
Free Memory:  515815488 (491.91998291015625 MiB)
Current PID is: 28274
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)

$ which java
/usr/bin/java
$ file /usr/bin/java
/usr/bin/java: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped, no debugging information available

$ prstat -p 28274
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
28274 user1     670M   32M sleep   59    0   0:00:00 0.0% java/35

BTW: เห็นได้ชัดว่า Java ไม่ได้จัดสรรหน่วยความจำจริงมากนักเมื่อเริ่มต้น ดูเหมือนว่าจะใช้เวลาเพียงประมาณ 100 MB ต่ออินสแตนซ์ที่เริ่มต้น (ฉันเริ่ม 10)

Solaris 10 - x86 - VMWare VM พร้อม RAM 8 GB (ฟรีประมาณ 3 GB *)

RAM ฟรี 3 GB นั้นไม่จริงเลย มี RAM ขนาดใหญ่ที่แคช ZFS ใช้ แต่ฉันไม่มีสิทธิ์เข้าถึงรูทเพื่อตรวจสอบว่าเท่าไหร่

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3650m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3600m MaxMemory
Total Memory: 516423680 (492.5 MiB)
Max Memory:   3355443200 (3200.0 MiB)
Free Memory:  513718336 (489.91998291015625 MiB)
Current PID is: 26841
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_41"
Java(TM) SE Runtime Environment (build 1.6.0_41-b02)
Java HotSpot(TM) Server VM (build 20.14-b01, mixed mode)

$ which java
/usr/bin/java

$ file /usr/bin/java
/usr/bin/java:  ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped, no debugging information available

$ prstat -p 26841
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
26841 user1     665M   22M sleep   59    0   0:00:00 0.0% java/12

RedHat 5.5 - x86 - VMWare VM พร้อม RAM 4 GB (ใช้ไปประมาณ 3.8 GB - บัฟเฟอร์ 200 MB และแคช 3.1 GB ดังนั้นฟรีประมาณ 3 GB)

$ alias java='$HOME/jre/jre1.6.0_34/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838768 (488.1274871826172 MiB)
Current PID is: 21879
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_34"
Java(TM) SE Runtime Environment (build 1.6.0_34-b04)
Java HotSpot(TM) Server VM (build 20.9-b04, mixed mode)

$ file $HOME/jre/jre1.6.0_34/bin/java
/home/user1/jre/jre1.6.0_34/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

$ cat /proc/21879/status | grep ^Vm
VmPeak:  3882796 kB
VmSize:  3882796 kB
VmLck:         0 kB
VmHWM:     12520 kB
VmRSS:     12520 kB
VmData:  3867424 kB
VmStk:        88 kB
VmExe:        40 kB
VmLib:     14804 kB
VmPTE:        96 kB

เครื่องเดียวกันที่ใช้ JRE 7

$ alias java='$HOME/jre/jre1.7.0_21/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838672 (488.1273956298828 MiB)
Current PID is: 23026
Waiting for user to press Enter to finish ...

$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Server VM (build 23.21-b01, mixed mode)

$ file $HOME/jre/jre1.7.0_21/bin/java
/home/user1/jre/jre1.7.0_21/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

$ cat /proc/23026/status | grep ^Vm
VmPeak:  4040288 kB
VmSize:  4040288 kB
VmLck:         0 kB
VmHWM:     13468 kB
VmRSS:     13468 kB
VmData:  4024800 kB
VmStk:        88 kB
VmExe:         4 kB
VmLib:     10044 kB
VmPTE:       112 kB

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

3

น่าจะดีกว่านี้เยอะ

สำหรับ JVM 32 บิตที่ทำงานบนโฮสต์ 64 บิตฉันคิดว่าสิ่งที่เหลืออยู่สำหรับฮีปจะเป็นพื้นที่เสมือนที่ไม่มีการแยกส่วนใด ๆ ที่มีอยู่หลังจาก JVM เป็น DLL ของตัวเองและสิ่งที่เข้ากันได้กับ OS 32 บิตถูกโหลดแล้ว ตามที่คาดเดาไว้ฉันคิดว่า 3GB น่าจะเป็นไปได้ แต่จะดีกว่าแค่ไหนนั้นขึ้นอยู่กับว่าคุณทำได้ดีแค่ไหนใน 32-bit-host-land

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

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

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

การโหลด DLL ขึ้นอยู่กับการนำไปใช้และการเปิดตัวของ JVM การโหลดเคอร์เนลระบบปฏิบัติการขึ้นอยู่กับหลายสิ่งหลายอย่างการเปิดตัว HW จำนวนสิ่งที่แมปไว้ตั้งแต่การรีบูตครั้งสุดท้ายใครจะรู้ ...

สรุป

ฉันเดิมพันที่คุณจะได้รับ 1-2 GB ใน 32 บิตที่ดินและประมาณ 3 ใน 64 บิตดังนั้นการปรับปรุงโดยรวมประมาณ2 เท่า


1
น่าเสียดายที่ฉันไม่มีสภาพแวดล้อม 64 บิตที่ฉันสามารถทดลองกับแฟล็ก Xmx ได้ สิ่งที่ฉันรู้จักมี RAM ขนาดมหึมา (32 * n) GB พร้อมใช้งาน แต่อยู่นอกขอบเขต นั่นคือเหตุผลที่ฉันอยากรู้ว่า JVM แบบ 32 บิตจะทำงานได้อย่างไรโดยไม่มีข้อ จำกัด ทั้งหมดที่ปกติต้องเผชิญในโลก 32 บิต
Vineet Reynolds

เป็นคำถามที่ดี ฉันแน่ใจว่าคำตอบพื้นฐานคือ "มันจะทำงานได้ดีขึ้น"
DigitalRoss

โอเคฉันได้แก้ไขคำตอบของฉันเพื่อเน้นคำถามจริงของคุณมากขึ้น :-)
DigitalRoss

1
≅ 3GB ในรูปแบบ 64 บิตให้เสียงที่เหมาะสม Thorbjørnได้ระบุแล้วว่าทำไมในทางทฤษฎีจึงไม่เกิน 4GB เสียดายที่ฉันไม่สามารถยอมรับสองคำตอบได้
Vineet Reynolds

หากคุณมีกล่องขนาดใหญ่คุณสามารถทดลองกับ Solaris 64 บิตในเช่น virtualbox (ซึ่งมีการสนับสนุนแขก Solaris ที่ดีที่สุด)
Thorbjørn Ravn Andersen

2

บน Solaris ขีด จำกัด อยู่ที่ประมาณ 3.5 GB ตั้งแต่ Solaris 2.5 (ประมาณ 10 ปีที่แล้ว)


ฉันจะทดลองใช้ Oracle Solaris Express 11
djangofan

1
@Peter Lawrey อืม .. Solaris 2.5 เกือบ 20 ปีที่แล้วถ้าคุณพิจารณาวันที่วางจำหน่ายพฤษภาคม 1996 .... แน่นอนว่ามันไม่ได้ EOL จนถึงประมาณปี 2005
cb88

1

ฉันประสบปัญหาเดียวกันกับ JVM ที่ App Inventor สำหรับ Android Blocks Editor ใช้ ตั้งค่าฮีปที่สูงสุด 925m นี่ยังไม่เพียงพอ แต่ฉันไม่สามารถตั้งค่าได้มากกว่า 1200m ขึ้นอยู่กับปัจจัยสุ่มต่างๆในเครื่องของฉัน

ฉันดาวน์โหลด Nightly เบราว์เซอร์เบต้า 64 บิตจาก Firefox และรุ่น JAVA 7 64 บิต

ฉันยังไม่พบขีด จำกัด ฮีพใหม่ของฉัน แต่ฉันเพิ่งเปิด JVM ที่มีขนาดฮีป5900m 5900mไม่มีปัญหา!

ฉันใช้ Win 7 64 bit Ultimate บนเครื่องที่มี RAM 24GB


0

ฉันได้ลองตั้งค่าขนาดฮีปไม่เกิน 2200M บนเครื่อง Linux 32 บิตและ JVM ทำงานได้ดี JVM ไม่เริ่มต้นเมื่อฉันตั้งค่าเป็น 2300M


ฉันคิดว่าฉันจะเพิ่มสิ่งนั้นใน Windows VISTA 64 บิต JVM 32 บิตสูงสุดที่ 1582m (ค่า -Xmx) มันจะบ่นถ้าฉันระบุ 1583m ฉันไม่ทราบว่าค่านี้เปลี่ยนจากเครื่องเป็นเครื่อง คอมพิวเตอร์ที่ฉันทดสอบนี้มี RAM จริง 4 GB
Santosh Tiwari

@SantoshTiwari มันเปลี่ยนจากเครื่องเป็นเครื่อง แต่นี่คือเหตุผล
Eugene


0

อีกจุดหนึ่งสำหรับฮอตสปอต JVM 32 บิต: - ความจุฮีปดั้งเดิม = 4 Gig - Java Heap - PermGen;

อาจเป็นเรื่องยุ่งยากเป็นพิเศษสำหรับ JVM 32 บิตเนื่องจาก Java Heap และเนทีฟ Heap อยู่ในการแข่งขัน ยิ่ง Java Heap ของคุณมีขนาดใหญ่เท่าใด Heap ดั้งเดิมก็จะยิ่งเล็กลง การพยายามตั้งค่า Heap ขนาดใหญ่สำหรับ VM 32 บิตเช่น. 2.5 GB + จะเพิ่มความเสี่ยงของ OutOfMemoryError ดั้งเดิมโดยขึ้นอยู่กับรอยเท้าแอปพลิเคชันของคุณจำนวนเธรด ฯลฯ


0

ข้อ จำกัด ยังมาจากข้อเท็จจริงที่ว่าสำหรับ32 bitVM heapนั้นตัวมันเองจะต้องเริ่มต้นที่ศูนย์ที่อยู่หากคุณต้องการสิ่งเหล่านี้ทั้งหมด4GBตัวเองมีการเริ่มต้นที่อยู่ที่ศูนย์ถ้าคุณต้องการทุกคน

ลองคิดดูหากคุณต้องการอ้างอิงบางสิ่งผ่าน:

0000....0001

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

    | ....               .... {heap_start .... heap_end} ... |
 --> (this can't be referenced) <--

เนื่องจากฮีปไม่เคยเริ่มต้นจากศูนย์ที่อยู่ใน an OSจึงมีบิตไม่กี่บิตที่ไม่เคยใช้จากการ32อ้างอิงบิตดังนั้นฮีปที่สามารถอ้างอิงได้จึงต่ำกว่า


-1

4gb ตามทฤษฎี แต่ในทางปฏิบัติ (สำหรับ IBM JVM):

รับรางวัล 2k8 64, IBM Websphere Application Server 8.5.5 32 บิต

C:\IBM\WebSphere\AppServer\bin>managesdk.bat -listAvailable -verbose CWSDK1003I: Доступные SDK: CWSDK1005I: Имя SDK: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=windows - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 - com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/win /x86_32/ CWSDK1001I: Задача managesdk выполнена успешно. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2036 MaxMemory JVMJ9GC017E -Xmx слишком мала, должна быть не меньше 1 M байт JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось инициализи ровать Could not create the Java virtual machine. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2047M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 2146435072 (2047.0 MiB) Free Memory: 3064536 (2.9225692749023438 MiB) C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2048M MaxMemory JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось создать эк земпляр кучи; запрошено 2G Could not create the Java virtual machine.

RHEL 6.4 64, IBM Websphere Application Server 8.5.5 32 บิต

[bin]./java -Xmx3791M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3975151616 (3791.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [root@nagios1p bin]# ./java -Xmx3793M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3977248768 (3793.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [bin]# /opt/IBM/WebSphere/AppServer/bin/managesdk.sh -listAvailable -verbose CWSDK1003I: Available SDKs : CWSDK1005I: SDK name: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=linux - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 -com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/linux/x86_32/ CWSDK1001I: Successfully performed the requested managesdk task.

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