Adakah yang bisa menjelaskan kepada saya mengapa JVM (saya tidak memeriksa terlalu banyak, tetapi saya belum pernah melihat yang tidak melakukannya dengan cara seperti itu) perlu dijalankan pada ukuran heap yang tetap? Saya tahu ini lebih mudah untuk diterapkan pada tumpukan berdekatan yang sederhana, tetapi Sun JVM sekarang berusia lebih dari satu dekade, jadi saya berharap mereka memiliki waktu untuk meningkatkan ini.
Perlu untuk menentukan ukuran memori maksimum dari program Anda pada waktu startup tampaknya merupakan hal yang harus dilakukan pada tahun 1960-an, dan kemudian ada interaksi yang buruk dengan manajemen memori virtual OS (pengambilan data yang bertukar dengan GC, ketidakmampuan untuk menentukan berapa banyak memori pada proses Java adalah benar - benar menggunakan dari sisi OS, sejumlah besar ruang VM terbuang (saya tahu, Anda tidak peduli pada mesin 48bit mewah Anda ...)). Saya juga menebak bahwa berbagai upaya menyedihkan untuk membangun sistem operasi kecil di dalam JVM (server aplikasi EE, OSGi) setidaknya sebagian untuk menyalahkan keadaan ini, karena menjalankan beberapa proses Java pada sistem selalu mengarah pada sumber daya yang terbuang karena Anda harus berikan masing-masing memori yang mungkin harus digunakan di puncak.
Anehnya, Google tidak menghasilkan badai kemarahan atas ini yang saya harapkan, tetapi mereka mungkin telah terkubur di bawah jutaan orang yang mencari tahu tentang ukuran tumpukan tetap dan hanya menerimanya sebagai fakta.
Jawaban:
Anda salah. Ukuran tumpukan JVM tidak diperbaiki, hanya dibatasi:
Pengaturan batas atas diperlukan karena beberapa alasan. Pertama, ia memberi tahu pengumpul sampah kapan harus bertindak. Kedua, ini mencegah JVM dari menyumbat seluruh mesin dengan memakan terlalu banyak memori. Ukuran heap minimum mungkin berguna untuk menyimpan jumlah memori yang paling tidak dibutuhkan oleh program, untuk mencegah kehabisan memori (karena proses lain mengonsumsi terlalu banyak).
sumber
Saya membayangkan jawabannya ada hubungannya dengan warisan Jawa. Ini awalnya dirancang sebagai bahasa yang akan digunakan untuk sistem embedded, di mana sumber daya jelas dibatasi dan Anda tidak ingin proses hanya melahap apa pun yang tersedia. Ini juga membantu administrasi sistem, karena memudahkan penyediaan sumber daya di server jika Anda dapat menetapkan batas sumber daya. Saya melihat bahwa JVM terbaru tampaknya menggunakan banyak tumpukan tidak kontinyu, meskipun tentu saja semuanya muncul sebagai tumpukan tunggal untuk kode Anda.
(FWIW, Anda harus menentukan persyaratan memori program di bawah versi MacOS pra-Darwin Apple [hingga Sistem 7, yang merupakan yang terakhir saya gunakan], yang sudah memasuki tahun 80-an.)
sumber
Anda perlu memberi beberapa GC mekanisme untuk memberitahu ketika menjalankan, atau program Anda akan mengisi seluruh ruang memori virtual. Ada banyak cara alternatif untuk memicu GC: waktu yang berlalu, jumlah alokasi, jumlah penugasan, mungkin yang lain yang tidak dapat saya pikirkan saat ini. IMO tidak ada yang sebaik mengatur batas memori, dan menjalankan GC ketika ruang yang dialokasikan mencapai batas itu.
Kuncinya adalah mengatur batas yang benar . Saya melihat
-ms
sebagai "ini adalah berapa banyak memori yang dibutuhkan aplikasi saya," dan-mx
"tidak boleh melebihi jumlah ini." Dalam penyebaran produksi, keduanya harus dekat jika tidak sama, dan mereka harus didasarkan pada persyaratan aktual dan terukur.Kekhawatiran Anda tentang memori virtual "terbuang" salah tempat: memori virtual, (hampir) gratis. Ya, memberi tumpukan terlalu besar peruntukan berarti Anda tidak dapat memulai banyak utas, atau memuat banyak file yang dipetakan memori. Tapi itu bagian dari desain aplikasi: Anda memiliki sumber daya yang langka, Anda perlu mempartisi mereka dengan cara yang memungkinkan aplikasi Anda untuk berjalan. Dalam tumpukan "C-style", yang akan meluas hingga Anda mencapai puncak memori, masalah dasarnya adalah sama, Anda tidak perlu memikirkannya sampai Anda dalam masalah.
Satu-satunya hal yang tumpukan besar "buang" adalah ruang swap, karena semua segmen yang dapat ditulis membutuhkan komitmen dari swap. Tapi itu adalah bagian dari desain sistem: jika Anda ingin memiliki banyak JVM berjalan pada kotak yang sama, baik meningkatkan swap Anda atau mengurangi penjatahan tumpukan mereka. Jika mereka mulai meronta-ronta, maka Anda mencoba melakukan terlalu banyak dengan sistem; beli lebih banyak memori (dan jika Anda masih menjalankan prosesor 32-bit, beli kotak baru).
sumber
Seperti kata user281377, Anda hanya menentukan batas atas dari berapa banyak memori yang dapat dikonsumsi oleh proses Anda . Tentu saja, aplikasi itu sendiri hanya akan mengambil ruang yang dibutuhkannya.
Apakah harus ada batas atas default atau tidak adalah pertanyaan lain, dengan pro dan kontra.
sumber