Ukuran heap Java maksimum dari JVM 32-bit pada OS 64-bit

107

Pertanyaannya bukanlah tentang ukuran heap maksimum pada OS 32-bit, mengingat OS 32-bit memiliki ukuran memori beralamat maksimum 4GB, dan bahwa ukuran heap maksimum JVM bergantung pada seberapa banyak memori bebas yang dapat dipesan.

Saya lebih tertarik untuk mengetahui ukuran heap maksimum (baik secara teoritis dan praktis) untuk JVM 32-bit yang berjalan di OS 64-bit. Pada dasarnya, saya melihat jawaban yang mirip dengan angka dalam pertanyaan terkait di SO .

Mengenai mengapa JVM 32-bit digunakan daripada yang 64-bit, alasannya bukan teknis melainkan administratif / birokrasi - mungkin sudah terlambat untuk menginstal JVM 64-bit di lingkungan produksi.

Vineet Reynolds
sumber

Jawaban:

70

JVM 32-bit yang diharapkan memiliki satu potongan besar memori dan menggunakan pointer mentah tidak dapat menggunakan lebih dari 4 Gb (karena itu adalah batas 32 bit yang juga berlaku untuk pointer). Ini termasuk Sun dan - saya cukup yakin - juga implementasi IBM. Saya tidak tahu apakah misalnya JRockit atau lainnya memiliki opsi memori yang besar dengan implementasi 32-bit mereka.

Jika Anda berharap untuk mencapai batas ini, Anda harus benar-benar mempertimbangkan untuk memulai track paralel yang memvalidasi JVM 64-bit untuk lingkungan produksi Anda sehingga Anda siap untuk itu ketika lingkungan 32-bit rusak. Jika tidak, Anda harus melakukan pekerjaan itu di bawah tekanan, yang tidak pernah menyenangkan.


Sunting 2014-05-15: FAQ Oracle:

Batas maksimum tumpukan teoretis untuk JVM 32-bit adalah 4G. Karena berbagai kendala tambahan seperti swap yang tersedia, penggunaan ruang alamat kernel, fragmentasi memori, dan overhead VM, dalam praktiknya, batasnya bisa jauh lebih rendah. Pada kebanyakan sistem Windows 32-bit modern, ukuran heap maksimum akan berkisar dari 1.4G hingga 1.6G. Pada kernel Solaris 32-bit, ruang alamat dibatasi hingga 2G. Pada sistem operasi 64-bit yang menjalankan VM 32-bit, ukuran heap maksimal bisa lebih tinggi, mendekati 4G di banyak sistem Solaris.

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

Thorbjørn Ravn Andersen
sumber
Tidak ada tekanan kerja di sini. Saya tahu bahwa JVM 64-bit seharusnya sudah diinstal sejak awal. Tapi itu membuat saya berpikir tentang bagaimana JVM 32-bit akan bekerja di lingkungan dengan lebih banyak sumber daya yang dimilikinya.
Vineet Reynolds
1
Bukankah sekitar 2GB karena penandatanganan? Atau itu hanya Sun JVM?
Sebastian Ganslandt
9
Pointer tidak ditandatangani - tidak masuk akal untuk membicarakan lokasi memori negatif.
Thorbjørn Ravn Andersen
12
Tidak, ini bukan 2GB karena tanda tangan. Namun, bagian dari ruang alamat 4GB dicadangkan untuk kernel OS. Pada versi konsumen normal Windows, batasnya adalah 2 GB. Di Linux dan versi server Windows (32-bit), batasnya adalah 3GB per proses.
Jesper
3
@Jesper Saya bertanya-tanya apakah JVM 32-bit yang berjalan pada sistem operasi 64-bit dapat memiliki ruang alamat 4 GB penuh yang tersedia?
Thorbjørn Ravn Andersen
90

Anda dapat menanyakan 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)");
    }
}

Ini akan melaporkan "Memori Maks" berdasarkan alokasi heap default. Jadi, Anda masih perlu bermain dengan -Xmx(di HotSpot ). Saya menemukan bahwa berjalan di Windows 7 Enterprise 64-bit, HotSpot JVM 32-bit saya dapat mengalokasikan hingga 1577MiB:

[C: awal]> java -Xmx1600M MaxMemory
Terjadi kesalahan selama inisialisasi VM
Tidak dapat memesan cukup ruang untuk tumpukan objek
Tidak dapat membuat mesin virtual java.
[C: awal]> java -Xmx1590M MaxMemory
Total Memori: 2031616 (1,9375 MiB)
Memori Maks: 1654456320 (1577.8125 MiB)
Memori Gratis: 1840872 (1,75559234619 MiB)
[C: awal]>

Sedangkan dengan JVM 64-bit di OS yang sama, tentunya jauh lebih tinggi (sekitar 3TiB)

[C: awal]> java -Xmx3560G MaxMemory
Terjadi kesalahan selama inisialisasi VM
Tidak dapat memesan cukup ruang untuk tumpukan objek
[C: awal]> java -Xmx3550G MaxMemory
Memori Total: 94240768 (89,875 MiB)
Memori Maks: 3388252028928 (3184151.84297 MiB)
Memori Gratis: 93747752 (89.4048233032 MiB)
[C: awal]>

Seperti yang telah disebutkan orang lain, itu tergantung pada OS.

  • Untuk Windows 32-bit: itu akan menjadi <2GB ( buku internal Windows mengatakan 2GB untuk proses pengguna)
  • Untuk 32-bit BSD / Linux: <3GB (dari Devil Book)
  • Untuk MacOS X 32-bit: <4GB (dari buku internal Mac OS X )
  • Tidak yakin tentang Solaris 32-bit, coba kode di atas dan beri tahu kami.

Untuk OS host 64-bit, jika JVM adalah 32-bit, itu masih akan bergantung, kemungkinan besar seperti di atas seperti yang ditunjukkan.

- PEMBARUAN 20110905 : Saya hanya ingin menunjukkan beberapa pengamatan / detail lainnya:

  • Perangkat keras tempat saya menjalankan ini adalah 64-bit dengan 6GB RAM aktual terpasang. Sistem operasinya adalah Windows 7 Enterprise, 64-bit
  • Jumlah sebenarnya Runtime.MaxMemoryyang dapat dialokasikan juga tergantung pada set kerja sistem operasi . Saya pernah menjalankan ini ketika saya juga menjalankan VirtualBox dan menemukan saya tidak berhasil memulai JVM HotSpot dengan -Xmx1590Mdan harus menjadi lebih kecil. Ini juga menyiratkan bahwa Anda mungkin mendapatkan lebih dari 1590M tergantung pada ukuran set kerja Anda pada saat itu (meskipun saya masih mempertahankannya di bawah 2GiB untuk 32-bit karena desain Windows)
mike
sumber
13
Saya suka Anda benar-benar menguji daripada membuat tebakan.
Jim Hurne
3
@djangan benar. Program harus dibagi dengan 1.048.576 (1024 * 1024, atau 2 ^ 20), bukan 104.856. Tapi, itu hanya tampilan. Seperti yang Anda lihat dari perintah, dia hanya mencoba mengatur ukuran heap maksimum menjadi 1.590 MiB.
Jim Hurne
1
Sangat dingin jawaban (saya ingin mengatakan pada jawaban), dengan contoh kode, dan detail yang mencakup semua OS.
TGP1994
3
Menindaklanjuti komentar saya sebelumnya: Jdocs (untuk windows atleast) menentukan bahwa parameter -Xmx dan -Xms harus diberi nilai kelipatan 1024 ... Saya tidak yakin apakah 1590, jadi menurut saya aneh hasil harus diharapkan.
TGP1994
4
TGP1994 terlihat baik. Saya pikir, karena saya telah menentukan kelipatan 'M' dan 'G', maka ukuran (dalam byte) akan menjadi kelipatan 1024 byte. misalnya 1590M akan diurai menjadi 1590 * (1024 * 1024) = 1667235840 byte (1628160KiB - tentu saja kelipatan 1024 genap).
mike
16

Anda tidak menentukan OS mana .

Di bawah Windows (untuk aplikasi saya - aplikasi manajemen risiko yang berjalan lama) kami mengamati bahwa kami tidak dapat melangkah lebih jauh dari 1280MB pada Windows 32bit. Saya ragu bahwa menjalankan JVM 32bit di bawah 64bit akan membuat perbedaan.

Kami mem-porting aplikasi ke Linux dan menjalankan JVM 32-bit pada perangkat keras 64-bit dan memiliki VM 2.2GB yang berjalan dengan cukup mudah.

Masalah terbesar yang mungkin Anda miliki adalah GC bergantung pada tujuan penggunaan memori Anda.

Fortyrunner
sumber
Saya lebih suka mengetahui batasan untuk Solaris 10, tetapi itu hanya untuk masalah saya yang ada. Ingin tahu untuk OS lain juga, untuk hari hujan :)
Vineet Reynolds
Tidak yakin tentang Solaris. Saya berharap ukuran VM cukup besar, pengalaman saya tentang Java di Solaris dari beberapa tahun yang lalu. Dan menjadi Sun VM pada Sun OS pada perangkat keras Sun - semuanya bekerja dengan baik. Saya juga dituntun untuk percaya bahwa ada lebih sedikit masalah GC di bawah Solaris daripada Linux / Windows.
Fortyrunner
Windows yang mana ini. Saya yakin versi server Windows 32-bit dapat menangani memori dalam jumlah besar dengan lebih baik.
Thorbjørn Ravn Andersen
Ah, akhirnya menyebutkan OS ;-) Anda memiliki kernel 64-bit yang diinstal?
Thorbjørn Ravn Andersen
Itu adalah server Win2k. Pindah ke Win2k3 (semuanya bergerak lambat ..) sudah terlambat dan kami beralih ke Linux sebagai gantinya.
Fortyrunner
14

Dari 4.1.2 Ukuran Heap :

"Untuk model proses 32-bit, ukuran alamat virtual maksimum dari proses biasanya 4 GB, meskipun beberapa sistem operasi membatasinya hingga 2 GB atau 3 GB. Ukuran heap maksimum biasanya -Xmx3800m (1600m) untuk batas 2 GB ), meskipun batasan sebenarnya bergantung pada aplikasi. Untuk model proses 64-bit, maksimum pada dasarnya tidak terbatas. "

Menemukan jawaban yang cukup bagus di sini: Memori maksimum Java pada Windows XP .

djangofan.dll
sumber
12

Kami baru saja mengalami beberapa pengalaman dengan ini. Kami baru-baru ini telah melakukan porting dari Solaris (x86-64 Versi 5.10) ke Linux (RedHat x86-64) dan menyadari bahwa kami memiliki lebih sedikit memori yang tersedia untuk proses JVM 32 bit di Linux daripada Solaris.

Untuk Solaris ini hampir mencapai 4GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

Kami menjalankan aplikasi kami dengan -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m tanpa masalah pada Solaris selama beberapa tahun terakhir. Mencoba memindahkannya ke linux dan kami mengalami masalah dengan kesalahan memori acak saat memulai. Kami hanya dapat menjalankannya secara konsisten pada -Xms2300 -Xmx2300 . Kemudian kami diberi tahu tentang hal ini dengan dukungan.

Proses 32 bit di Linux memiliki ruang alamat maksimum yang dapat dialamatkan sebesar 3gb (3072mb) sedangkan di Solaris adalah 4gb penuh (4096mb).

chinto
sumber
Alasan jawaban yang diberikan oleh dukungan terletak pada seberapa banyak memori yang dapat dialamatkan tersedia untuk suatu proses. Ini tergantung pada kernel Linux dan bahkan pada perangkat keras. Secara teoritis, memori yang dapat dialamatkan dibatasi hingga 2 ^ 32 = 4G (dan ukuran heap Java akan lebih kecil dari ini). Tapi, ini (secara teoritis) dapat diperpanjang dengan menggunakan hugemem dan PAE; Saya belum mencoba ini.
Vineet Reynolds
9

Batasan JVM 32-bit pada OS 64-bit akan sama persis dengan batasan JVM 32-bit pada OS 32-bit. Bagaimanapun, JVM 32-bit akan berjalan di mesin virtual 32-bit (dalam arti virtualisasi) sehingga ia tidak akan tahu bahwa itu berjalan pada OS / mesin 64-bit.

Satu keuntungan menjalankan JVM 32-bit pada OS 64-bit dibandingkan dengan OS 32-bit adalah Anda dapat memiliki lebih banyak memori fisik, dan oleh karena itu akan lebih jarang mengalami pertukaran / paging. Namun, keuntungan ini hanya benar-benar terwujud ketika Anda memiliki banyak proses.

Laurence Gonsalves
sumber
1
Mungkin ada sedikit perbedaan tergantung pada perangkat keras dan cara virtualisasi. Beberapa ruang beralamat 4GB umumnya digunakan untuk perangkat yang dipetakan memori. Lapisan virtualisasi mungkin atau mungkin tidak memiliki jejak memori yang sama dengan perangkat fisik pada mesin.
Eric J.
8
Tidak terlalu. Ada lebih banyak ruang untuk JVM di mesin 64-bit karena ruang alamat 32-bit tidak harus digunakan bersama dengan sistem operasi atau antarmuka perangkat keras.
Thorbjørn Ravn Andersen
Itu benar, tetapi semua itu berarti bahwa mesin virtual 32-bit Anda mungkin memiliki overhead yang sedikit berbeda dari mesin 32-bit-aktual (lebih buruk, atau lebih baik). Apa pun itu, Anda menjalankan JVM pada mesin 32-bit (nyata atau virtual) sehingga Anda akan tunduk pada batasan standar 32-bit. yaitu: plafon absolut 4GB.
Laurence Gonsalves
Thorbjørn: sistem operasi dan antarmuka perangkat keras masih perlu dipetakan ke dalam VM 32-bit. Jumlah tepatnya yang terdengar mungkin berbeda, tetapi itu akan tetap ada. Jika Anda dapat memvirtualisasikannya di bawah OS 64-bit, apa yang menghentikan Anda untuk memvirtualisasikannya di bawah OS 32-bit? Ini adalah memori virtual yang sedang kita bicarakan.
Laurence Gonsalves
2
LG: Saya tidak setuju dengan jawaban asli Anda. Kernel OS dan setiap HW dan ruang alamat bus yang dipetakan akan memakan banyak ruang alamat, dan sementara ini tidak dipetakan ke dalam program pengguna, itu mengurangi jumlah "yang tersisa" setelah OS mengatur dirinya sendiri. Ini adalah jumlah yang cukup besar dari ruang 4GB 32-bit. Secara tradisional, ini berarti bahwa sekitar 25% -75% dari 4GB tidak tersedia untuk proses pengguna. :-) peretas kernel
DigitalRoss
6

Mengenai mengapa JVM 32-bit digunakan daripada yang 64-bit, alasannya bukan teknis melainkan administratif / birokrasi ...

Ketika saya bekerja untuk BEA, kami menemukan bahwa rata-rata aplikasi benar-benar berjalan lebih lambat di JVM 64-bit, lalu berjalan lebih lambat di JVM 32-bit. Dalam beberapa kasus, kinerja mencapai 25% lebih lambat. Jadi, kecuali aplikasi Anda benar-benar membutuhkan semua memori ekstra itu, lebih baik Anda menyiapkan lebih banyak server 32-bit.

Seingat saya, tiga alasan teknis paling umum untuk menggunakan 64-bit yang dialami oleh personel layanan profesional BEA adalah:

  1. Aplikasi itu memanipulasi banyak gambar besar,
  2. Aplikasi ini melakukan pemrosesan angka besar-besaran,
  3. Aplikasi tersebut memiliki kebocoran memori, pelanggan adalah yang utama dalam kontrak pemerintah, dan mereka tidak ingin menghabiskan waktu dan biaya untuk melacak kebocoran memori. (Menggunakan tumpukan memori yang besar akan meningkatkan MTBF dan prime tetap akan dibayar)

.

pengguna1564349
sumber
Bagus sekali Anda memberikan nasihat langsung, mantan pekerja BEA :)
emecas
4

JROCKIT JVM yang saat ini dimiliki oleh Oracle mendukung penggunaan heap yang tidak bersebelahan, sehingga memungkinkan JVM 32 bit untuk mengakses lebih dari 3,8 GB memori saat JVM berjalan pada OS Windows 64 bit. (2,8 GB saat berjalan pada OS 32 bit).

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

JVM dapat diunduh secara bebas (perlu registrasi) di

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

Lembah
sumber
4

Berikut adalah beberapa pengujian di bawah Solaris dan Linux 64-bit

Solaris 10 - SPARC - Mesin T5220 dengan RAM 32 GB (dan gratis sekitar 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: Rupanya Java tidak mengalokasikan banyak memori aktual saat startup. Tampaknya hanya membutuhkan sekitar 100 MB per contoh dimulai (saya mulai 10)

Solaris 10 - x86 - VMWare VM dengan RAM 8 GB (gratis sekitar 3 GB *)

RAM 3 GB gratis tidak benar. Ada sebagian besar RAM yang digunakan cache ZFS, tetapi saya tidak memiliki akses root untuk memeriksa seberapa tepatnya

$ 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 dengan RAM 4 GB (sekitar 3,8 GB digunakan - 200 MB di buffer dan 3,1 GB di cache, jadi gratis sekitar 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

Mesin yang sama menggunakan 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
ih.ng
sumber
Ada beberapa hasil pengujian yang berguna di sini untuk platform yang kami lewatkan. Kerja bagus dengan penggunaan file dan memory dump juga.
mike
3

Seharusnya jauh lebih baik

Untuk JVM 32-bit yang berjalan pada host 64-bit, saya membayangkan apa yang tersisa untuk heap adalah ruang virtual apa pun yang tidak terfragmentasi yang tersedia setelah JVM, DLL itu sendiri, dan semua hal kompatibilitas 32-bit OS telah dimuat. Sebagai tebakan liar saya akan berpikir 3GB seharusnya mungkin, tetapi seberapa jauh lebih baik itu tergantung pada seberapa baik Anda melakukannya di tanah tuan rumah 32-bit.

Selain itu, meskipun Anda dapat membuat heap 3GB yang besar, Anda mungkin tidak mau, karena ini akan menyebabkan jeda GC berpotensi menjadi masalah. Beberapa orang hanya menjalankan lebih banyak JVM untuk menggunakan memori ekstra daripada satu memori raksasa. Saya membayangkan mereka sedang menyetel JVM sekarang untuk bekerja lebih baik dengan tumpukan raksasa.

Agak sulit untuk mengetahui dengan tepat seberapa jauh Anda bisa lebih baik. Saya kira situasi 32-bit Anda dapat dengan mudah ditentukan oleh eksperimen. Memang sulit untuk memprediksi secara abstrak, karena banyak faktor di dalamnya, terutama karena ruang virtual yang tersedia pada host 32-bit agak dibatasi .. Heap memang perlu ada dalam memori virtual yang berdekatan, jadi fragmentasi ruang alamat untuk dll dan penggunaan internal ruang alamat oleh kernel OS akan menentukan kisaran alokasi yang memungkinkan.

OS akan menggunakan beberapa ruang alamat untuk memetakan perangkat HW dan alokasi dinamisnya sendiri. Meskipun memori ini tidak dipetakan ke dalam ruang alamat proses java, kernel OS tidak dapat mengaksesnya dan ruang alamat Anda pada saat yang bersamaan, sehingga akan membatasi ukuran ruang virtual program apa pun.

Memuat DLL bergantung pada implementasi dan rilis JVM. Memuat kernel OS tergantung pada sejumlah besar hal, rilis, HW, berapa banyak hal yang telah dipetakan sejauh ini sejak reboot terakhir, siapa tahu ...

Singkatnya

Saya yakin Anda mendapatkan 1-2 GB di tanah 32-bit, dan sekitar 3 di 64-bit, jadi peningkatan keseluruhan sekitar 2x .

DigitalRoss
sumber
1
Sayangnya, saya tidak memiliki lingkungan 64-bit yang dapat saya gunakan untuk bereksperimen dengan tanda Xmx. Yang saya tahu memiliki jumlah RAM yang sangat besar (32 * n) GB yang tersedia, tetapi di luar batas. Itulah mengapa saya ingin tahu bagaimana JVM 32-bit akan bekerja tanpa semua kendala yang biasanya dihadapinya di dunia 32-bit.
Vineet Reynolds
Nah, pertanyaan yang bagus. Saya yakin jawaban dasarnya adalah "ini akan bekerja lebih baik".
DigitalRoss
Oke, saya telah mengedit jawaban saya untuk lebih fokus pada pertanyaan Anda yang sebenarnya. :-)
DigitalRoss
1
≅ 3GB dalam 64-bit terdengar pas. Thorbjørn telah menunjukkan mengapa secara teoritis tidak dapat melebihi 4GB. Sayang sekali saya tidak bisa menerima dua jawaban.
Vineet Reynolds
Jika Anda memiliki kotak besar , Anda dapat bereksperimen dengan Solaris 64-bit di misalnya kotak virtual (yang memiliki dukungan tamu Solaris terbaik).
Thorbjørn Ravn Andersen
2

Di Solaris, batasnya sekitar 3,5 GB sejak Solaris 2.5. (sekitar 10 tahun yang lalu)

Peter Lawrey
sumber
Saya akan bereksperimen dengan itu, menggunakan Oracle Solaris Express 11.
djangofan
1
@Peter Lawrey Uhm .. Solaris 2.5 hampir 20 tahun yang lalu jika Anda mempertimbangkan tanggal rilis Mei 1996 .... tentu saja itu tidak EOL sampai sekitar 2005.
cb88
1

Saya mengalami masalah yang sama dengan JVM yang digunakan App Inventor untuk Android Blocks Editor. Ini menyetel heap pada maks. 925m. Ini tidak cukup tetapi saya tidak dapat menyetelnya lebih dari sekitar 1200m, tergantung pada berbagai faktor acak pada mesin saya.

Saya mengunduh Nightly, browser beta 64-bit dari Firefox, dan juga versi JAVA 7 64 bit.

Saya belum menemukan batas heap baru saya, tetapi saya baru saja membuka JVM dengan ukuran heap 5900m . Tidak masalah!

Saya menjalankan Win 7 64 bit Ultimate pada mesin dengan RAM 24 GB.

pengguna1652651
sumber
0

Saya telah mencoba mengatur ukuran heap hingga 2200M pada mesin Linux 32bit dan JVM berfungsi dengan baik. JVM tidak dimulai saat saya setel ke 2300M.

Priya
sumber
Saya pikir saya akan menambahkannya pada Windows VISTA 64 bit, JVM 32 bit maksimal pada 1582m (nilai -Xmx). Ini akan mengeluh jika saya menentukan 1583m. Saya tidak tahu apakah nilai ini berubah dari mesin ke mesin. Komputer yang saya uji ini sebenarnya memiliki RAM fisik 4 GB.
Santosh Tiwari
@SantoshTiwari berubah dari mesin ke mesin, tetapi inilah alasannya
Eugene
0

satu poin lagi di sini untuk hotspot 32-bit JVM: - kapasitas tumpukan asli = 4 Gig - Java Heap - PermGen;

Ini bisa menjadi sangat rumit untuk JVM 32-bit karena Heap Java dan Heap asli sedang bersaing. Semakin besar Java Heap Anda, semakin kecil Heap asli. Mencoba menyiapkan Heap besar untuk VM 32-bit misalnya .2.5 GB + meningkatkan risiko OutOfMemoryError asli bergantung pada footprint aplikasi Anda, jumlah Thread, dll.

ajay29
sumber
0

Batasan juga berasal dari fakta bahwa untuk 32 bitVM, heapitu sendiri harus dimulai dari alamat nol jika Anda menginginkan semua itu 4GB.

Pikirkanlah, jika Anda ingin mereferensikan sesuatu melalui:

0000....0001

yaitu: referensi yang memiliki representasi bit khusus ini, artinya Anda mencoba mengakses memori pertama dari heap. Agar bisa, heap harus dimulai dari alamat nol. Tapi itu tidak pernah terjadi, itu dimulai dengan beberapa offset dari nol:

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

Karena heap tidak pernah dimulai dari alamat nol di an OS, ada beberapa bit yang tidak pernah digunakan dari 32referensi bit, dan karena itu heap yang dapat direferensikan lebih rendah.

Eugene
sumber
-1

Teoritis 4gb, tetapi dalam praktiknya (untuk IBM JVM):

Menangkan 2k8 64, Server Aplikasi IBM Websphere 8.5.5 32bit

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, Server Aplikasi IBM Websphere 8.5.5 32bit

[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.

pk.shulgin
sumber