Memori maksimum Java pada Windows XP


103

Saya selalu dapat mengalokasikan 1400 megabyte untuk Java SE yang berjalan pada Windows XP 32-bit (Java 1.4, 1.5 dan 1.6).

java -Xmx1400m ...

Hari ini saya mencoba opsi yang sama pada mesin Windows XP baru menggunakan Java 1.5_16 dan 1.6.0_07 dan mendapatkan kesalahan:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Melalui trial and error, tampaknya 1200 megabyte adalah jumlah terbesar yang dapat saya alokasikan untuk mesin ini.

Adakah ide mengapa satu mesin mengizinkan 1400 dan yang lainnya hanya 1200?

Sunting: Mesin memiliki RAM 4GB dengan sekitar 3,5GB yang dapat dikenali Windows.


Anda akan melihat perbedaan maksimum antara menjalankan aplikasi di shell 32-bit atau shell 64-bit, setidaknya menurut pengalaman saya, meskipun sistem WindowsXP 64-bit jarang terjadi.
djangofan

Jawaban:


124

Perlu diingat bahwa Windows memiliki manajemen memori virtual dan JVM hanya membutuhkan memori yang berdekatan dalam ruang alamatnya . Jadi, program lain yang berjalan pada sistem seharusnya tidak memengaruhi ukuran heap Anda. Apa yang akan menghalangi Anda adalah DLL yang dimuat ke ruang alamat Anda. Sayangnya, pengoptimalan di Windows yang meminimalkan relokasi DLL selama penautan membuat kemungkinan Anda akan memiliki ruang alamat yang terfragmentasi. Hal-hal yang cenderung memotong ruang alamat Anda selain dari hal-hal biasa termasuk perangkat lunak keamanan, perangkat lunak CBT, spyware, dan bentuk malware lainnya. Kemungkinan penyebab perbedaan adalah patch keamanan yang berbeda, versi runtime C, dll. Driver perangkat dan bit kernel lainnya memiliki ruang alamat sendiri (2 GB lainnya dari ruang 32-bit 4 GB).

Anda dapat mencoba melalui binding DLL Anda dalam proses JVM Anda dan mencoba untuk me-rebase DLL Anda ke dalam ruang alamat yang lebih ringkas. Tidak menyenangkan, tetapi jika Anda putus asa ...

Atau, Anda bisa beralih ke Windows 64-bit dan JVM 64-bit. Terlepas dari apa yang disarankan orang lain, meskipun itu akan mengunyah lebih banyak RAM, Anda akan memiliki ruang alamat virtual yang jauh lebih berdekatan, dan mengalokasikan 2GB secara berdekatan akan sepele.


5
Gunakan Process Explorer untuk melihat di mana memori dll sedang dimuat. Seringkali beberapa driver yang diperbarui akan menempel di tengah ruang alamat Anda. Dengan menggunakan perintah REBASE Anda dapat dengan mudah menyingkirkannya. Perlu diingat, dll dapat diperbarui lagi dan merusak barang.
Brianegge

2
Saya tidak pernah menerima ini sebagai jawaban, namun stackoverflow menandainya sebagai jawaban.
Steve Kuo

@ Christopher, Apakah mungkin menggunakan JVM 64-bit pada Windows XP 32-bit?
Pacerier

@Pacerier Maaf, saya melewatkan pertanyaan Anda. AFAIK, itu tidak mungkin. OS X memiliki beberapa trik untuk ruang pengguna 64-bit dengan kernel 32-bit, tetapi saya belum pernah mendengar hal seperti itu untuk Windows.
Christopher Smith

@ChristopherSmith, Btw, Anda menyebutkan " program lain yang berjalan di sistem seharusnya tidak memengaruhi ukuran heap Anda ". Jika demikian, bagaimana kami menjelaskan hasil ini: stackoverflow.com/questions/9303889/… ?
Pacerier

50

Ini ada hubungannya dengan memori yang berdekatan.

Berikut beberapa info yang saya temukan online untuk seseorang yang menanyakan hal itu sebelumnya, diduga dari "Dewa VM":

Alasan kita memerlukan wilayah memori yang berdekatan untuk heap adalah karena kita memiliki sekumpulan struktur data samping yang diindeks oleh offset (yang diskalakan) dari awal heap. Misalnya, kami melacak pembaruan referensi objek dengan "larik tanda kartu" yang memiliki satu byte untuk setiap 512 byte heap. Saat kita menyimpan referensi di heap, kita harus menandai byte yang sesuai dalam larik tanda kartu. Kami menggeser alamat tujuan toko dan menggunakannya untuk mengindeks array tanda kartu. Permainan aritmatika yang menyenangkan yang tidak dapat Anda lakukan di Java yang harus Anda (harus :-) mainkan di C ++.

Biasanya kami tidak mengalami kesulitan untuk mendapatkan wilayah berdekatan yang sederhana (hingga sekitar 1,5 GB di Windohs, hingga sekitar 3,8 GB di Solaris. YMMV.). Di Windohs, masalahnya sebagian besar adalah ada beberapa pustaka yang dimuat sebelum JVM dimulai yang memecah ruang alamat. Menggunakan sakelar / 3GB tidak akan me-rebase pustaka tersebut, jadi mereka masih menjadi masalah bagi kami.

Kami tahu cara membuat tumpukan yang terpecah, tetapi akan ada biaya tambahan untuk menggunakannya. Kami memiliki lebih banyak permintaan untuk pengelolaan penyimpanan yang lebih cepat daripada yang kami lakukan untuk heaps yang lebih besar di JVM 32-bit. Jika Anda benar-benar menginginkan tumpukan besar, alihkan ke JVM 64-bit. Kami masih membutuhkan memori yang berdekatan, tetapi jauh lebih mudah untuk mendapatkan di ruang alamat 64-bit.


Ini sangat menarik. Saya selalu bertanya pada diri sendiri mengapa 1500 MB, sekarang saya mendapatkannya, terima kasih!
Tim Büthe

3
Maaf untuk menindaklanjuti pertanyaan lama, tapi ini adalah jawaban terbaik yang saya lihat sejauh ini. Tetapi mengapa JVM gagal saat startup jika tidak bisa mendapatkan ukuran heap maksimum ? Bukankah seharusnya diam-diam menerima ukuran terbaik di atas minimum ?
Stroboskop

19

Batas ukuran heap Java untuk Windows adalah:

  • ukuran heap maksimum yang memungkinkan pada Java 32-bit: 1,8 GB
  • batas ukuran heap yang disarankan pada Java 32-bit: 1,5 GB (atau 1,8 GB dengan / opsi 3GB)

Ini tidak membantu Anda mendapatkan heap Java yang lebih besar, tetapi sekarang Anda tahu bahwa Anda tidak dapat melampaui nilai-nilai ini.


10

Oracle JRockit , yang dapat menangani heap yang tidak bersebelahan, dapat memiliki ukuran heap Java 2,85 GB pada Windows 2003 / XP dengan sakelar / 3GB. Tampaknya fragmentasi dapat berdampak cukup besar pada seberapa besar tumpukan Java.


6

JVM membutuhkan memori yang berdekatan dan tergantung pada apa lagi yang sedang berjalan, apa yang berjalan sebelumnya, dan bagaimana jendela mengelola memori, Anda mungkin dapat memperoleh hingga 1,4GB memori yang berdekatan. Saya pikir 64bit Windows akan memungkinkan tumpukan yang lebih besar.


2
Saya pikir sistem operasi modern meniru memori berkelanjutan untuk. Sejak 80486, arsitektur x86 mendukung paging untuk memudahkan pengaturan ulang memori fisik.
Mnementh

3
Mnemeth: Pertama, ada API khusus (AllocateUserPhysicalPages) di WINAPI untuk alat tingkat lanjut seperti database dan VM yang lebih baik dalam mengelola memori mereka sendiri dengan Windows yang tidak berfungsi. Kedua, paging adalah fitur mode terlindung 80386, bukan 80486.
Tamas Czinege

6

JVM Sun membutuhkan memori yang berdekatan. Jadi jumlah maksimal memori yang tersedia ditentukan oleh fragmentasi memori. Terutama dll driver cenderung memecah memori, saat memuat ke beberapa alamat dasar yang telah ditentukan. Jadi perangkat keras Anda dan drivernya menentukan berapa banyak memori yang bisa Anda dapatkan.

Dua sumber untuk ini dengan pernyataan dari insinyur Sun: blog forum

Mungkin JVM lain? Sudahkah Anda mencoba Harmony ? Saya pikir mereka berencana untuk mengizinkan memori non-kontinu.


Tetapi saya dapat mengalokasikan 1300MB pada mesin dengan hanya 1GB RAM (ditambah memori virtual). Mesin RAM 2GB saya (juga dengan memori virtual) hanya dapat mengalokasikan 1200MB.
Steve Kuo

Harmoni sudah mati bukan?
Pacerier

Ya: "Apache Harmony dihentikan di Apache Software Foundation sejak 16 November 2011."
bobbel

3

Saya pikir ini lebih berkaitan dengan bagaimana Windows dikonfigurasi seperti yang diisyaratkan oleh tanggapan ini: Opsi Java -Xmx

Beberapa pengujian lagi: Saya dapat mengalokasikan 1300MB pada mesin Windows XP lama dengan hanya 768MB RAM fisik (ditambah memori virtual). Di mesin RAM 2GB saya, saya hanya bisa mendapatkan 1220MB. Di berbagai mesin perusahaan lainnya (dengan Windows XP yang lebih lama) saya bisa mendapatkan 1400MB. Mesin dengan batas 1220MB cukup baru (baru saja dibeli dari Dell), jadi mungkin memiliki Windows dan DLL yang lebih baru (dan lebih membengkak) (menjalankan Window XP Pro Version 2002 SP2).


Itu juga dapat dipengaruhi oleh pengaturan Memori Virtual Anda.
Skaffman

Semua mesin yang saya uji memiliki memori virtual setidaknya dua kali RAM fisik.
Steve Kuo

perhatikan bahwa Anda benar-benar tidak ingin benar-benar menggunakan memori virtual dengan java, karena kinerja GC akan menjadi sangat buruk. Jumlah memori tergantung pada dll mana yang telah dimuat dan telah memecah memori.
kohlerm

2

Saya mendapat pesan kesalahan ini saat menjalankan program java dari VPS virtuozzo (memori terbatas). Saya belum menentukan argumen memori apa pun, dan ternyata saya harus menetapkan jumlah yang kecil secara eksplisit karena defaultnya pasti terlalu tinggi. Misalnya -Xmx32m (jelas perlu disetel tergantung pada program yang Anda jalankan).

Letakkan ini di sini jika ada orang lain yang mendapatkan pesan kesalahan di atas tanpa menentukan sejumlah besar memori seperti yang dilakukan penanya.


1

JDK / JRE sun membutuhkan jumlah memori yang berdekatan jika Anda mengalokasikan blok yang sangat besar.

OS dan aplikasi awal cenderung mengalokasikan potongan-potongan selama memuat fragmen RAM yang tersedia. Jika blok yang berdekatan TIDAK tersedia, SUN JDK tidak dapat menggunakannya. JRockit dari Bea (diakuisisi oleh Oracle) dapat mengalokasikan memori dari beberapa bagian.


1

Semua orang tampaknya menjawab tentang memori yang berdekatan, tetapi telah mengabaikan untuk mengakui masalah yang lebih mendesak.

Bahkan dengan 100% alokasi memori yang berdekatan, Anda tidak dapat memiliki ukuran heap 2 GiB pada OS Windows 32-bit (* secara default). Ini karena proses Windows 32-bit tidak dapat menangani lebih dari 2 GiB ruang.

Proses Java akan berisi perm gen (sebelum Java 8), ukuran stack per thread, overhead JVM / library (yang meningkat cukup banyak dengan setiap build) semua selain heap .

Lebih lanjut, flag JVM dan nilai defaultnya berubah antar versi. Jalankan saja yang berikut dan Anda akan mendapatkan beberapa ide:

 java -XX:+PrintFlagsFinal

Banyak opsi yang memengaruhi pembagian memori masuk dan keluar dari heap. Memberi Anda lebih atau kurang dari 2 GiB untuk dimainkan ...

Untuk menggunakan kembali bagian-bagian dari ini jawaban saya (sekitar Tomcat, tetapi berlaku untuk setiap proses Java):

OS Windows membatasi alokasi memori dari proses 32-bit menjadi 2 GiB secara total (secara default).

[Anda hanya akan dapat] mengalokasikan sekitar 1,5 GiB ruang heap karena ada juga memori lain yang dialokasikan untuk proses (overhead JVM / perpustakaan, ruang perm gen, dll.).

Mengapa Windows 32-bit memberlakukan batas ruang alamat proses 2 GB, tetapi Windows 64-bit memberlakukan batas 4 GB?

Sistem operasi modern lainnya [batuk Linux] memungkinkan proses 32-bit untuk menggunakan semua (atau sebagian besar) dari ruang beralamat 4 GiB.

Meskipun demikian, OS Windows 64-bit dapat dikonfigurasi untuk meningkatkan batas proses 32-bit menjadi 4 GiB (3 GiB pada 32-bit):

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx


1
Jawaban ini hanya membahas mengapa ia mungkin hanya dapat mengalokasikan 2 GB, bukan mengapa ia dapat mengalokasikan 1,4 GB di satu komputer dan hanya 1,2 GB di komputer lain. Dia tidak mencapai batas 1,5 GB, 2 GB, atau 4 GB Anda yang disebutkan di sini.
vapcguy

1
Paragraf pada flag JVM menjelaskan beberapa cara untuk menjelaskan mengapa memori dapat bervariasi antar versi. Juga, perhatikan poin saya tentang bagaimana pengaturan heap selalu merupakan sebagian kecil (besar) dari ukuran proses total - jadi pengaturan di bawah ini yang mungkin masih mencapai batas proses 2 GiB - yang lain mungkin dibatasi oleh alokasi memori yang berdekatan.
Michael

Atau mungkin batas 1,5 GB, pada alokasi 1,4 GB itu dia lakukan. Lebih masuk akal sekarang - terima kasih atas klarifikasi itu.
vapcguy

0

Berikut adalah cara meningkatkan ukuran Paging

  1. klik kanan pada mycomputer ---> properties ---> Advanced
  2. di pengaturan klik bagian kinerja
  3. klik tab Advanced
  4. di bagian Memori virtual, klik ubah. Ini akan menunjukkan ukuran halaman Anda saat ini.
  5. Pilih Drive dimana ruang HDD tersedia.
  6. Berikan ukuran awal dan ukuran maksimal ... misalnya ukuran awal 0 MB dan ukuran maksimal 4000 MB. (Sebanyak yang Anda butuhkan)

0

** Ada banyak cara untuk mengubah ukuran heap seperti,

  1. file-> setting-> build, exceution, deployment-> compiler di sini Anda akan menemukan ukuran heap
  2. file-> setting-> build, exceution, deployment-> compiler-> andriod di sini juga Anda akan menemukan ukuran heap. Anda dapat merujuk ini untuk proyek andriod jika Anda menghadapi masalah yang sama.

Apa yang berhasil bagi saya adalah

  1. Setel jalur JAVA_HOME yang tepat jika java Anda diperbarui.

  2. buat variabel sistem baru komputer-> properti-> pengaturan lanjutan- > buat variabel sistem baru

name: _JAVA_OPTION value: -Xmx750m

FYI: Anda dapat menemukan VMoption default di bantuan Intellij- > edit opsi VM kustom , Di file ini Anda melihat ukuran minimum dan maksimum heap. **


-1

Pertama, menggunakan file halaman saat Anda memiliki RAM 4 GB tidak berguna. Windows tidak dapat mengakses lebih dari 4GB (sebenarnya, kurang karena lubang memori) sehingga file halaman tidak digunakan.

Kedua, ruang alamat dibagi menjadi 2, setengah untuk kernel, setengah untuk mode pengguna. Jika Anda membutuhkan lebih banyak RAM untuk aplikasi Anda, gunakan opsi / 3GB di boot.ini (pastikan java.exe ditandai sebagai "alamat besar sadar" (google untuk info lebih lanjut).

Ketiga, saya pikir Anda tidak dapat mengalokasikan ruang alamat 2 GB penuh karena java membuang beberapa memori secara internal (untuk utas, kompiler JIT, inisialisasi VM, dll). Gunakan sakelar / 3GB untuk lebih.


1
Gagasan bahwa file halaman tidak berguna dengan 4GB atau RAM adalah salah. Tanpa berkas halaman, sistem operasi tidak dapat mengeluarkan data proses yang tidak digunakan (ruang tumpukan untuk layanan yang tidak digunakan, dll) dari RAM fisik, sehingga menurunkan jumlah RAM yang tersedia untuk pekerjaan nyata. Memiliki pagefile membebaskan RAM.
tidak ada orang
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.