Penggunaan Memori Virtual dari Java di Linux, terlalu banyak memori yang digunakan

259

Saya punya masalah dengan aplikasi Java yang berjalan di Linux.

Ketika saya meluncurkan aplikasi, menggunakan ukuran tumpukan maksimum default (64 MB), saya melihat menggunakan aplikasi puncak yang 240 MB Memori virtual dialokasikan ke aplikasi. Ini menciptakan beberapa masalah dengan beberapa perangkat lunak lain di komputer, yang relatif terbatas sumber daya.

Memori virtual yang dicadangkan tidak akan digunakan, sejauh yang saya mengerti, karena begitu kita mencapai batas tumpukan dan OutOfMemoryErrordilemparkan. Saya menjalankan aplikasi yang sama di bawah windows dan saya melihat bahwa ukuran Memori Virtual dan ukuran Heap serupa.

Apakah ada cara lain yang dapat saya atur Memori Virtual yang digunakan untuk proses Java di Linux?

Sunting 1 : Masalahnya bukan Heap. Masalahnya adalah jika saya menetapkan Heap 128 MB, misalnya, Linux masih mengalokasikan 210 MB Memori Virtual, yang tidak diperlukan, selamanya. **

Sunting 2 : Menggunakan ulimit -vmemungkinkan membatasi jumlah memori virtual. Jika ukuran yang ditetapkan di bawah 204 MB, maka aplikasi tidak akan berjalan meskipun tidak perlu 204 MB, hanya 64 MB. Jadi saya ingin mengerti mengapa Java membutuhkan begitu banyak memori virtual. Bisakah ini diubah?

Sunting 3 : Ada beberapa aplikasi lain yang berjalan di sistem, yang tertanam. Dan sistem memang memiliki batas memori virtual (dari komentar, detail penting).

Mario Ortegón
sumber
Mengapa Anda khawatir dengan penggunaan memori virtual? Jika Anda benar-benar ingin khawatir, lihat penggunaan memori penduduk dan baca perintah berikut: gratis, ps, atas.
basszero
2
Ada beberapa aplikasi lain yang berjalan di sistem, yang tertanam. Dan sistem memang memiliki batas memori virtual.
Mario Ortegón
ahhhh, iblis ada dalam rincian
basszero
Implementasi Java mana yang Anda gunakan. IIRC, standar bog (non-OpenJDK) gratis Sun JRE tidak dilisensikan untuk penggunaan tertanam.
Tom Hawtin - tackline
Saya pikir saya salah menggunakan bagian "tertanam" ... itu adalah memori terbatas dan perangkat keras disesuaikan, tetapi masih komputer standar
Mario Ortegón

Jawaban:

630

Ini sudah lama menjadi keluhan dengan Java, tetapi sebagian besar tidak ada artinya, dan biasanya didasarkan pada melihat informasi yang salah. Ungkapan yang biasa adalah sesuatu seperti "Halo Dunia di Jawa membutuhkan 10 megabita! Mengapa perlu itu?" Nah, inilah cara untuk membuat Hello World pada JVM 64-bit mengklaim untuk mengambil alih 4 gigabytes ... setidaknya dengan satu bentuk pengukuran.

java -Xms1024m -Xmx4096m com.example.Halo

Cara Berbeda untuk Mengukur Memori

Di Linux, perintah teratas memberi Anda beberapa angka berbeda untuk memori. Inilah yang dikatakan tentang contoh Hello World:

  PID PENGGUNA PR NI VIRT RES SHR S% CPU% MEM TIME + PERINTAH
 2120 kggregory 20 0 4373m 15m 7152 S 0 0.2 0: 00.10 java
  • VIRT adalah ruang memori virtual: jumlah semua yang ada di peta memori virtual (lihat di bawah). Sebagian besar tidak ada artinya, kecuali kalau tidak (lihat di bawah).
  • RES adalah ukuran yang ditetapkan residen: jumlah halaman yang saat ini resident dalam RAM. Dalam hampir semua kasus, ini adalah satu-satunya nomor yang harus Anda gunakan ketika mengatakan "terlalu besar." Tapi itu masih bukan angka yang sangat baik, terutama ketika berbicara tentang Jawa.
  • SHR adalah jumlah memori penduduk yang dibagi dengan proses lain. Untuk proses Java, ini biasanya terbatas pada perpustakaan bersama dan JARfiles yang dipetakan memori. Dalam contoh ini, saya hanya menjalankan satu proses Java, jadi saya curiga bahwa 7k adalah hasil dari pustaka yang digunakan oleh OS.
  • SWAP tidak diaktifkan secara default, dan tidak ditampilkan di sini. Ini menunjukkan jumlah memori virtual yang saat ini ada pada disk, terlepas dari apakah itu benar-benar ada di ruang swap . OS sangat baik untuk menjaga halaman aktif dalam RAM, dan satu-satunya obat untuk bertukar adalah (1) membeli lebih banyak memori, atau (2) mengurangi jumlah proses, jadi yang terbaik adalah mengabaikan nomor ini.

Situasi untuk Windows Task Manager sedikit lebih rumit. Di bawah Windows XP, ada kolom "Penggunaan Memori" dan "Ukuran Memori Virtual", tetapi dokumentasi resmi tidak menjelaskan apa artinya. Windows Vista dan Windows 7 menambahkan lebih banyak kolom, dan sebenarnya didokumentasikan . Dari jumlah tersebut, pengukuran "Perangkat Kerja" adalah yang paling berguna; kira-kira sama dengan jumlah RES dan SHR di Linux.

Memahami Peta Memori Virtual

Memori virtual yang dikonsumsi oleh suatu proses adalah total semua yang ada di peta memori proses. Ini termasuk data (misalnya, tumpukan Java), tetapi juga semua perpustakaan bersama dan file yang dipetakan memori yang digunakan oleh program. Di Linux, Anda dapat menggunakan perintah pmap untuk melihat semua hal yang dipetakan ke dalam ruang proses (mulai sekarang saya hanya akan merujuk ke Linux, karena itulah yang saya gunakan; Saya yakin ada alat yang setara untuk Windows). Berikut ini kutipan dari peta memori program "Hello World"; seluruh peta memori memiliki panjang lebih dari 100 baris, dan bukan tidak biasa memiliki daftar seribu baris.

0000000040000000 36K rx-- /usr/local/java/jdk-1.6-x64/bin/java
0000000040108000 8K rwx-- /usr/local/java/jdk-1.6-x64/bin/java
0000000040eba000 676K rwx-- [anon]
00000006fae00000 21248K rwx-- [anon]
00000006fc2c0000 62720K rwx-- [anon]
0000000700000000 699072K rwx-- [anon]
000000072aab0000 2097152K rwx-- [anon]
00000007aaab0000 349504K rwx-- [anon]
00000007c0000000 1048576K rwx-- [anon]
...
00007fa1ed00d000 1652K r-xs- /usr/local/java/jdk-1.6-x64/jre/lib/rt.jar
...
00007fa1ed1d3000 1024K rwx-- [anon]
00007fa1ed2d3000 4K ----- [anon]
00007fa1ed2d4000 1024K rwx-- [anon]
00007fa1ed3d4000 4K ----- [anon]
...
00007fa1f20d3000 164K rx-- /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f20fc000 1020K ----- /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f21fb000 28K rwx-- /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
...
00007fa1f34aa000 1576K rx-- /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3634000 2044K ----- /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3833000 16K rx-- /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3837000 4K rwx-- /lib/x86_64-linux-gnu/libc-2.13.so
...

Penjelasan cepat format: setiap baris dimulai dengan alamat memori virtual segmen. Ini diikuti oleh ukuran segmen, izin, dan sumber segmen. Item terakhir ini adalah file atau "anon", yang menunjukkan blok memori yang dialokasikan melalui mmap .

Mulai dari atas, sudah

  • Pemuat JVM (yaitu, program yang dijalankan saat Anda mengetik java). Ini sangat kecil; semua yang dilakukannya adalah memuat di pustaka bersama tempat kode JVM asli disimpan.
  • Sekelompok blok anon memegang heap Java dan data internal. Ini adalah Sun JVM, jadi tumpukannya dibagi menjadi beberapa generasi, yang masing-masingnya merupakan blok memori sendiri. Perhatikan bahwa JVM mengalokasikan ruang memori virtual berdasarkan -Xmxnilai; ini memungkinkannya untuk memiliki tumpukan yang berdekatan. The -Xmsnilai digunakan secara internal untuk mengatakan berapa banyak tumpukan adalah "digunakan" ketika program dimulai, dan untuk pengumpulan sampah pemicu batas yang didekati.
  • JARfile yang dipetakan dengan memori, dalam hal ini file yang menampung "kelas JDK." Ketika Anda memetakan memori sebuah JAR, Anda dapat mengakses file di dalamnya dengan sangat efisien (dibandingkan membacanya dari awal setiap kali). Sun JVM akan memetakan-memori semua JAR di classpath; jika kode aplikasi Anda perlu mengakses JAR, Anda juga dapat memetakannya dalam memori.
  • Data per-utas untuk dua utas. Blok 1M adalah tumpukan ulir. Saya tidak memiliki penjelasan yang baik untuk blok 4k, tetapi @ericsoe mengidentifikasinya sebagai "blok penjaga": ia tidak memiliki izin baca / tulis, sehingga akan menyebabkan kesalahan segmen jika diakses, dan JVM menangkap itu dan menerjemahkan itu ke StackOverFlowError. Untuk aplikasi nyata, Anda akan melihat puluhan jika tidak ratusan entri ini diulang melalui peta memori.
  • Salah satu pustaka bersama yang menyimpan kode JVM yang sebenarnya. Ada beberapa di antaranya.
  • Pustaka bersama untuk pustaka standar C. Ini hanyalah salah satu dari banyak hal yang dimuat JVM yang tidak sepenuhnya bagian dari Jawa.

Pustaka bersama sangat menarik: setiap pustaka bersama memiliki setidaknya dua segmen: segmen hanya baca yang berisi kode perpustakaan, dan segmen baca-tulis yang berisi data per proses global untuk perpustakaan (saya tidak tahu apa segmen tanpa izin adalah; Saya hanya melihatnya di x64 Linux). Bagian read-only perpustakaan dapat dibagi antara semua proses yang menggunakan perpustakaan; misalnya, libcmemiliki ruang memori virtual 1,5M yang dapat dibagi.

Kapan Ukuran Memori Virtual Penting?

Peta memori virtual berisi banyak hal. Beberapa di antaranya hanya-baca, sebagian dibagikan, dan sebagian dialokasikan tetapi tidak pernah disentuh (misalnya, hampir semua tumpukan 4Gb dalam contoh ini). Tetapi sistem operasi cukup pintar untuk hanya memuat apa yang dibutuhkan, sehingga ukuran memori virtual sebagian besar tidak relevan.

Di mana ukuran memori virtual penting adalah jika Anda menjalankan sistem operasi 32-bit, di mana Anda hanya dapat mengalokasikan 2Gb (atau, dalam beberapa kasus, 3Gb) ruang alamat proses. Dalam hal ini Anda berhadapan dengan sumber daya yang langka, dan mungkin harus melakukan pengorbanan, seperti mengurangi ukuran tumpukan Anda untuk memetakan memori file besar atau membuat banyak utas.

Tetapi, mengingat bahwa mesin 64-bit ada di mana-mana, saya pikir itu tidak akan lama sebelum Ukuran Memori Virtual adalah statistik yang sama sekali tidak relevan.

Kapan Resident Mengatur Ukuran Penting?

Ukuran Resident Set adalah porsi ruang memori virtual yang sebenarnya ada dalam RAM. Jika RSS Anda tumbuh menjadi bagian yang signifikan dari total memori fisik Anda, mungkin ini saatnya untuk mulai khawatir. Jika RSS Anda tumbuh untuk mengambil semua memori fisik Anda, dan sistem Anda mulai bertukar, sudah lewat waktu untuk mulai khawatir.

Tapi RSS juga menyesatkan, terutama pada mesin yang ringan. Sistem operasi tidak menghabiskan banyak upaya untuk merebut kembali halaman yang digunakan oleh suatu proses. Ada sedikit manfaat yang bisa diperoleh dengan melakukannya, dan potensi kesalahan halaman yang mahal jika proses menyentuh halaman di masa depan. Akibatnya, statistik RSS dapat menyertakan banyak halaman yang tidak digunakan secara aktif.

Intinya

Kecuali jika Anda bertukar, jangan terlalu khawatir tentang apa yang dikatakan berbagai statistik memori. Dengan peringatan bahwa RSS yang terus tumbuh dapat mengindikasikan semacam kebocoran memori.

Dengan program Java, jauh lebih penting untuk memperhatikan apa yang terjadi di heap. Jumlah total ruang yang digunakan adalah penting, dan ada beberapa langkah yang dapat Anda ambil untuk menguranginya. Yang lebih penting adalah jumlah waktu yang Anda habiskan dalam pengumpulan sampah, dan bagian mana dari tumpukan yang dikumpulkan.

Mengakses disk (yaitu, database) mahal, dan memori murah. Jika Anda dapat berdagang satu untuk yang lain, lakukanlah.

kdgregory
sumber
9
Anda harus mempertimbangkan bahwa bagian memori yang saat ini ditukar hilang dari ukuran RES. Jadi Anda mungkin memiliki nilai RES yang rendah tetapi hanya karena aplikasi tidak aktif dan banyak tumpukan yang ditukar ke disk. Java melakukan pekerjaan yang sangat buruk untuk swap: Pada setiap GC penuh sebagian besar heap berjalan dan disalin sehingga jika banyak tumpukan Anda di swap, GC harus memuat semuanya kembali ke memori utama.
jrudolph
1
Jawaban bagus kdgregory! Saya menjalankan dalam lingkungan tertanam menggunakan CF yang tidak memiliki ruang swap. Jadi berdasarkan jawaban Anda, semua nilai VIRT, SWAP, dan nFLT saya berasal dari file yang dipetakan memori ... yang sekarang masuk akal untuk di-war. Apakah Anda tahu jika nilai SWAP mewakili halaman yang belum dimuat ke memori atau halaman yang telah ditukar keluar dari memori, atau keduanya? Bagaimana kita bisa mendapatkan ide kemungkinan meronta-ronta (peta kontinu lalu tukar keluar)?
Jeach
2
@Jeach - Saya terkejut bahwa ada swap yang dilaporkan, jadi saya boot "traveling Linux" (thumb drive dengan Ubuntu 10.04 dan tanpa swap). Ketika saya mengaktifkan kolom "SWAP" di atas , saya melihat Eclipse memiliki 509m. Ketika saya kemudian melihatnya dengan pmap , total ruang virtual adalah 650m. Jadi saya menduga bahwa angka "SWAP" mewakili semua halaman di disk, bukan hanya yang tidak ada di memori.
kdgregory
2
Adapun pertanyaan kedua Anda: jika Anda terus membaca halaman dari kartu flash, waktu tunggu IO Anda (ditunjukkan dalam ringkasan atas sebagai "% wa") harus tinggi. Berhati-hatilah, bagaimanapun, bahwa ini akan tinggi untuk aktivitas apa pun, terutama menulis (dengan asumsi bahwa program Anda melakukan apapun)
kdgregory
1
> Blok 1M adalah tumpukan ulir; Saya tidak tahu apa yang masuk ke blok 4K. Blok 4K - yang ditandai sebagai tidak memiliki izin baca atau tulis - kemungkinan merupakan blok penjaga. Pada stack overflow, area ini diakses, yang memicu kesalahan, yang kemudian dapat ditangani oleh JVM dengan membuat Java StackOverflowException. Ini jauh lebih murah daripada memeriksa stack pointer pada setiap pemanggilan metode. Area penjaga tanpa izin yang ditetapkan juga dapat terlihat digunakan dalam konteks lain.
eriksoe
38

Ada masalah yang diketahui dengan Java dan glibc> = 2.10 (termasuk Ubuntu> = 10.04, RHEL> = 6).

Obatnya adalah mengatur env ini. variabel:

export MALLOC_ARENA_MAX=4

Jika Anda menjalankan Tomcat, Anda dapat menambahkan ini ke TOMCAT_HOME/bin/setenv.shfile.

Untuk Docker, tambahkan ini ke Dockerfile

ENV MALLOC_ARENA_MAX=4

Ada artikel IBM tentang pengaturan MALLOC_ARENA_MAX https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

Posting blog ini mengatakan

memori penduduk telah dikenal merayap dengan cara yang mirip dengan kebocoran memori atau fragmentasi memori.

Ada juga bug JDK terbuka JDK-8193521 "glibc menghabiskan memori dengan konfigurasi default"

cari MALLOC_ARENA_MAX di Google atau SO untuk referensi lainnya.

Anda mungkin ingin menyetel juga opsi malloc lainnya untuk dioptimalkan agar fragmentasi rendah dari memori yang dialokasikan:

# tune glibc memory allocation, optimize for low fragmentation
# limit the number of arenas
export MALLOC_ARENA_MAX=2
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt"
export MALLOC_MMAP_THRESHOLD_=131072
export MALLOC_TRIM_THRESHOLD_=131072
export MALLOC_TOP_PAD_=131072
export MALLOC_MMAP_MAX_=65536
Lari Hotari
sumber
Jawaban ini benar-benar membantu saya di Server 64bit Ubuntu dengan server TomEE yang mendapat litte untuk "mengkonsumsi-mem". Tautan ke artikel IBM benar-benar merupakan penjelasan yang mendalam. Sekali lagi terima kasih atas petunjuk yang baik ini!
MWiesner
1
JVM mungkin bocor memori asli yang mengarah ke gejala yang serupa. Lihat stackoverflow.com/a/35610063/166062 . Contoh GZIPInputStream dan GZIPOutputStream yang tidak tertutup mungkin menjadi sumber kebocoran juga.
Lari Hotari
3
Ada bug JVM di Java 8, yang menghasilkan pertumbuhan memori asli yang tidak terbatas: bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8164293 - Jika ini mempengaruhi Anda, menggunakan MALLOC_ARENA_MAXmungkin memperlambat pertumbuhan memori Anda, tetapi tidak menyelesaikan masalah sepenuhnya.
outofcoffee
@LariHotari sangat menghargai upaya Anda untuk menunjukkan versi glibc dan redhat
Sam
2
Java 8u131 berisi perbaikan bug yang di-backport untuk bug JVM terkait JDK-8164293 bugs.openjdk.java.net/browse/JDK-8178124 .
Lari Hotari
9

Jumlah memori yang dialokasikan untuk proses Java cukup setara dengan apa yang saya harapkan. Saya punya masalah serupa menjalankan Java pada embedded / memory system terbatas. Menjalankan aplikasi apa pun dengan batas VM sewenang-wenang atau pada sistem yang tidak memiliki jumlah swap yang memadai cenderung rusak. Tampaknya menjadi sifat dari banyak aplikasi modern yang tidak dirancang untuk digunakan pada sistem terbatas sumber daya.

Anda memiliki beberapa opsi lagi yang dapat Anda coba dan batasi jejak memori JVM Anda. Ini mungkin mengurangi jejak memori virtual:

-XX: ReservedCodeCacheSize = 32m Ukuran cache kode cadangan (dalam byte) - ukuran cache kode maksimum. [Solaris 64-bit, amd64, dan -server x86: 48m; dalam 1.5.0_06 dan sebelumnya, Solaris 64-bit dan and64: 1024m.]

-XX: MaxPermSize = Ukuran 64m dari Generasi Permanen. [5.0 dan yang lebih baru: VM 64 bit diskalakan 30% lebih besar; 1.4 amd64: 96m; 1.3.1 -pelanggan: 32m.]

Selain itu, Anda juga harus mengatur -Xmx (ukuran tumpukan maksimum) ke nilai sedekat mungkin dengan penggunaan memori puncak aktual aplikasi Anda. Saya percaya perilaku default JVM masih dua kali lipat ukuran heap setiap kali itu memperluas hingga max. Jika Anda mulai dengan tumpukan 32 juta dan aplikasi Anda memuncak menjadi 65 juta, maka tumpukan akan berakhir dengan pertumbuhan 32 juta -> 64 juta -> 128 juta.

Anda mungkin juga mencoba ini untuk membuat VM kurang agresif tentang menumbuhkan tumpukan:

-XX: MinHeapFreeRatio = 40 Persentase minimum tumpukan bebas setelah GC untuk menghindari ekspansi.

Juga, dari apa yang saya ingat dari percobaan dengan ini beberapa tahun yang lalu, jumlah perpustakaan asli dimuat memiliki dampak besar pada jejak minimum. Memuat java.net.Socket menambahkan lebih dari 15 juta jika saya mengingat dengan benar (dan saya mungkin tidak).

James Schek
sumber
7

Sun JVM membutuhkan banyak memori untuk HotSpot dan memetakan di pustaka runtime dalam memori bersama.

Jika memori menjadi masalah, pertimbangkan untuk menggunakan JVM lain yang cocok untuk disematkan. IBM memiliki j9, dan ada Open Source "jamvm" yang menggunakan perpustakaan classpath GNU. Sun juga memiliki Squeak JVM yang berjalan di SunSPOT jadi ada alternatif lain.

Thorbjørn Ravn Andersen
sumber
Apakah ini opsi untuk menonaktifkan hot spot?
Mario Ortegón
Mungkin. Periksa opsi baris perintah untuk JVM yang Anda gunakan.
Thorbjørn Ravn Andersen
3

Hanya berpikir, tetapi Anda dapat memeriksa pengaruh sebuah ulimit -vpilihan .

Itu bukan solusi aktual karena akan membatasi ruang alamat yang tersedia untuk semua proses, tetapi itu akan memungkinkan Anda untuk memeriksa perilaku aplikasi Anda dengan memori virtual terbatas.

VONC
sumber
Persis seperti itulah masalah saya. Heap saya diatur ke 64M, tetapi linux cadangan 204MB. Jika saya mengatur ulimit di bawah 204, aplikasi tidak berjalan sama sekali.
Mario Ortegón
Menarik: pengaturan ulimit mungkin memiliki efek samping yang tidak diinginkan untuk proses lain, menjelaskan mengapa aplikasi tidak dapat berjalan.
VonC
Masalahnya tampaknya bahwa Java mengharuskan untuk memesan jumlah memori Virtual yang lebih besar ini meskipun itu tidak akan menggunakannya. Di windows, memori virtual yang digunakan dan pengaturan Xmx agak lebih dekat.
Mario Ortegón
Apakah Anda mencobanya dengan JRockit JVM?
VonC
Karena alokasi memori JVM adalah jumlah dari Alokasi Heap dan Ukuran Perm (yang pertama dapat diperbaiki menggunakan opsi -Xms dan -Xmx), apakah Anda mencoba beberapa pengaturan dengan -XX: PermSize dan -XX: MaxPermSize (default dari 32MB ke 64MB tergantung pada versi JVM)?
VonC
3

Salah satu cara mengurangi tumpukan heile dari suatu sistem dengan sumber daya terbatas mungkin dengan bermain-main dengan variabel -XX: MaxHeapFreeRatio. Ini biasanya diatur ke 70, dan persentase maksimum tumpukan yang gratis sebelum GC menyusut. Menetapkannya ke nilai yang lebih rendah, dan Anda akan melihat misalnya profiler jvisualvm bahwa sice heap yang lebih kecil biasanya digunakan untuk program Anda.

Sunting: Untuk menetapkan nilai kecil untuk -XX: MaxHeapFreeRatio Anda juga harus mengatur -XX: MinHeapFreeRatio Misalnya

java -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25 HelloWorld

EDIT2: Menambahkan contoh untuk aplikasi nyata yang memulai dan melakukan tugas yang sama, satu dengan parameter default dan satu dengan 10 dan 25 sebagai parameter. Saya tidak melihat adanya perbedaan kecepatan nyata, meskipun java secara teori harus menggunakan lebih banyak waktu untuk meningkatkan heap pada contoh terakhir.

Parameter default

Pada akhirnya, max heap adalah 905, heap yang digunakan adalah 378

MinHeap 10, MaxHeap 25

Pada akhirnya, max heap adalah 722, heap yang digunakan adalah 378

Ini sebenarnya memiliki beberapa inpact, karena aplikasi kita berjalan pada server desktop jarak jauh, dan banyak pengguna dapat menjalankannya sekaligus.

runholen
sumber
1

Sun's Java 1.4 memiliki argumen berikut untuk mengontrol ukuran memori:

-Xmsn Tentukan ukuran awal, dalam byte, dari kumpulan alokasi memori. Nilai ini harus kelipatan 1024 lebih besar dari 1MB. Tambahkan huruf k atau K untuk menunjukkan kilobyte, atau m atau M untuk menunjukkan megabita. Nilai standarnya adalah 2MB. Contoh:

           -Xms6291456
           -Xms6144k
           -Xms6m

-Xmxn Menentukan ukuran maksimum, dalam byte, dari kumpulan alokasi memori. Nilai ini harus kelipatan 1024 lebih besar dari 2MB. Tambahkan huruf k atau K untuk menunjukkan kilobyte, atau m atau M untuk menunjukkan megabita. Nilai default adalah 64MB. Contoh:

           -Xmx83886080
           -Xmx81920k
           -Xmx80m

http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html

Java 5 dan 6 memiliki lebih banyak. Lihat http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

Paul Tomblin
sumber
1
Masalah yang saya miliki bukan dengan Ukuran Heap, tetapi dengan jumlah Memori Virtual yang ditugaskan oleh Linux
Mario Ortegón
Baca penjelasan kdgregory. Mengurangi ukuran tumpukan, "Ukuran baru", dan parameter yang dapat dikonfigurasi lainnya akan mengurangi jumlah memori NYATA yang dibutuhkan jvm.
Paul Tomblin
Dia mungkin memiliki masalah yang sah. Beberapa aplikasi (seperti yang saya tulis) mmap file 1 GB dan beberapa sistem hanya memiliki 2 GB memori virtual, beberapa di antaranya akan diisi dengan shared library. Dan jika ini masalahnya dia pasti harus menonaktifkan pengacakan DSO. Ada opsi di / proc.
Zan Lynx
0

Tidak, Anda tidak dapat mengonfigurasi jumlah memori yang dibutuhkan oleh VM. Namun, perhatikan bahwa ini adalah memori virtual, bukan residen, jadi itu hanya tinggal di sana tanpa membahayakan jika tidak benar-benar digunakan.

Secara alternatif, Anda dapat mencoba beberapa JVM lain kemudian Sun satu, dengan jejak memori yang lebih kecil, tapi saya tidak bisa menyarankan di sini.

Marko
sumber