.NET Out Of Memory Exception - Digunakan 1,3GB tetapi 16GB telah diinstal

91

Saya mendapatkan pengecualian Memori Habis di aplikasi c # saya saat penggunaan memori untuk aplikasi tersebut melebihi 1,3 GB.

Saya mengalami masalah yang sama pada mesin 32-bit dengan memori 3gb dan itu masuk akal saat itu, tetapi sekarang saya meningkatkan perangkat keras ke mesin 64-bit dengan memori 16GB dengan motherboard dan RAM kelas atas tetapi Keluar Dari Memori pengecualian masih terjadi setelah 1,3GB!

Saya tahu bahwa tidak ada satu pun objek di atas 2GB dan 1,3 kurang dari 2GB, jadi batas MS 2GB bawaan pada satu objek tidak mungkin menjadi masalah ...

Sepertinya ada semacam tombol pemutus jendela ketika aplikasi mencapai ambang batas penggunaan memori tertentu ... Lalu harus ada cara untuk mengonfigurasinya, mungkinkah ini di registri?

Bantuan apa pun akan sangat dihargai!

Paceman
sumber
9
Apakah OS Anda 64bit juga?
fge
9
Bahkan jika OS Anda 64bit, pastikan proses Anda juga 64bit (atau AnyCPU)
Knowleech

Jawaban:

90

Tidak ada perbedaan sampai Anda mengkompilasi ke arsitektur target yang sama. Saya kira Anda sedang mengompilasi 32arsitektur bit dalam kedua kasus.

Perlu disebutkan bahwa OutOfMemoryExceptionjuga dapat dimunculkan jika Anda mendapatkan 2GBmemori yang dialokasikan oleh satu koleksi dalam CLR (katakanlah List<T>) pada kedua arsitektur 32dan 64bit.

Untuk dapat memanfaatkan kebaikan memori pada 64arsitektur bit, Anda harus mengompilasi64 arsitektur bit penargetan kode Anda . Setelah itu, tentu saja, biner Anda hanya akan berjalan dalam 64bit, tetapi akan mendapatkan keuntungan dari kemungkinan memiliki lebih banyak ruang yang tersedia di RAM.

Tigran
sumber
8
Bagaimana dengan AnyCPU?
dtb
1
Ya, AnyCPU juga merupakan opsi, di mana Anda memiliki opsi untuk kode yang bergantung pada arsitektur JIT. Namun menargetkan arsitektur tertentu tetap dapat bermanfaat, jika Anda memiliki resource yang tidak dikelola (katakanlah). Saya tidak tahu tentang apa itu arsitektur OP.
Tigran
4
Saya tahu bahwa :) - Terima kasih Tigran, saya membangun kembali solusi di x64 dan pengecualiannya hilang.
Paceman
63

Seperti yang telah disebutkan, mengompilasi aplikasi di x64 memberi Anda lebih banyak memori yang tersedia.

Namun dalam kasus seseorang harus membangun aplikasi di x86, ada cara untuk meningkatkan batas memori dari 1,2GB menjadi 4GB (yang merupakan batas sebenarnya untuk proses 32 bit):

Di folder VC / bin dari direktori penginstalan Visual Studio, harus ada editbin.exefile. Jadi dalam instalasi default saya, saya menemukannya di bawah

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\editbin.exe

Agar program bisa berjalan, mungkin Anda harus mengeksekusi vcvars32.batdi direktori yang sama terlebih dahulu. Kemudian a

editbin /LARGEADDRESSAWARE <your compiled exe file>

cukup untuk membiarkan program Anda menggunakan RAM 4GB. <your compiled exe file>adalah exe, yang dihasilkan VS saat menyusun proyek Anda.

Jika Anda ingin mengotomatiskan perilaku ini setiap kali Anda mengompilasi proyek Anda, gunakan event Post-Build berikut untuk proyek yang dijalankan:

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)

Catatan: Hal yang sama dapat dilakukan dengan devenv.exemembiarkan Visual Studio juga menggunakan RAM 4GB, bukan 1.2GB (tapi backup dulu yang lama devenv.exe).

Desty
sumber
Terima kasih banyak. Ini berhasil untuk saya. Tetapi apakah kami memiliki masalah yang teridentifikasi setelah menaikkan batas memori menjadi 4GB.
Maverick
28

Perlu disebutkan bahwa default untuk kompilasi 'Setiap CPU' sekarang mencentang kotak 'Pilih 32bit'. Karena disetel ke AnyCPU, pada OS 64bit dengan RAM 16 GB masih dapat mencapai pengecualian memori sebesar 2 GB jika ini dicentang.

Prefer32BitCheckBox

tonycoupland.dll
sumber
2
Ini benar-benar menyelesaikan masalah memori saya dan menyelamatkan kami dari satu ton frustrasi
RSSM
2

Sepertinya Anda memiliki lengkungan 64-bit, bagus - tapi versi 32-bit dari runtime .NET dan / atau Windows versi 32-bit.

Dan karena itu, ruang alamat yang tersedia untuk proses Anda masih sama, itu tidak berubah dari penyiapan Anda sebelumnya.

Tingkatkan ke OS 64bit dan versi 64bit .NET;)

fge
sumber
1

Apakah aplikasi Anda berjalan sebagai proses 64 atau 32bit? Anda dapat memeriksanya di pengelola tugas.

Bisa jadi, ini berjalan sebagai 32bit, meski seluruh sistem berjalan pada 64bit.

Jika 32bit, perpustakaan pihak ketiga dapat menyebabkan ini. Tapi pertama-tama pastikan aplikasi Anda sedang mengkompilasi untuk "Semua CPU", seperti yang dinyatakan di komentar.

Jacco
sumber
0

Jika Anda memiliki Windows 32-bit, metode ini tidak berfungsi tanpa pengaturan berikut.

  1. Jalankan cmd.exe prompt (penting: Jalankan Sebagai Administrator)
  2. ketik bcdedit.exe dan jalankan
  3. Lihatlah parameter "peningkatanuserva" dan tidak ada kemudian tulis pernyataan berikut
  4. bcdedit / set peningkatanuserva 3072
  5. dan lagi langkah 2 dan periksa params

Kami menambahkan pengaturan ini dan pemblokiran ini dimulai.

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)

Info selengkapnya - perintah increaseuserva: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/bcdedit--set

Mehmet Kurt
sumber