OutOfMemoryException pada mesin tertentu saat menjalankan tes

Kami memiliki pengujian pengujian NUnit yang mengalami OutOfMemoryExceptions pada mesin tertentu.

Setelah diselidiki sepertinya ini bukan masalah memori, tapi masalah Handle (kami mengalokasikan terlalu banyak objek Bitmap dan tidak melepaskannya).

Masalahnya adalah, ini berjalan dengan sempurna di mesin tertentu, sementara gagal dengan kesalahan ini di mesin lain.

  1. Mesin yang gagal adalah VM Hyper-V dengan Windows7 x64 (ram 6 GB)
  2. Mesin Kerja adalah mesin fisik Windows XP (ram 2 GB)

Saya tahu bahwa solusi terbaik adalah membersihkan kode untuk membuang objek Bitmap apa pun, tetapi saya tertarik untuk mengetahui mengapa 2 mesin ini berbeda perilakunya saat menjalankan kode yang sama?


person lysergic-acid    schedule 30.09.2013    source sumber
comment
Kerangka .NET mungkin sama, tetapi OS yang mendasarinya tidak. Sumber daya seperti bitmap masih ditangani oleh sistem operasi. Windows 7 menangani sumber daya secara berbeda dibandingkan Windows XP, jadi tidak mengherankan jika Anda mendapatkan hasil yang berbeda pada versi Windows yang berbeda.   -  person helb    schedule 30.09.2013
comment
Jumlah pegangan yang dapat bocor sebelum Windows menolak mengeluarkannya lagi dapat dikonfigurasi. Mungkin salah satu mesin dikonfigurasi secara berbeda.   -  person Eric Lippert    schedule 30.09.2013
comment
Terima kasih @eric. Tahukah Anda dari mana hal ini dapat dikendalikan?   -  person lysergic-acid    schedule 30.09.2013
comment
@lysergic-acid: Ini adalah situs tanya jawab. Ajukan pertanyaan sebagai pertanyaan!   -  person Eric Lippert    schedule 30.09.2013


Jawaban (2)


Baca ini: http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx

Anda akan menemukan tabel perbedaan antara berbagai versi Windows sehubungan dengan tumpukan GDI. Jawaban singkatnya: XP = batas 3Mb, Win7R2x64 = batas 20Mb. RAM gratis tidak masalah, ini adalah batasan yang sulit.

person jlew    schedule 30.09.2013
comment
Ini tidak sejalan dengan fakta bahwa di XP tidak crash dan di Win7 crash :( - person lysergic-acid; 30.09.2013
comment
Bisa saja kondisimu berbanding terbalik dengan sekarang - person jlew; 30.09.2013

Itu tidak mungkin, Windows mengizinkan Anda membocorkan 10.000 pegangan sebelum menjadi rewel tentang perilaku program Anda dan menolak membiarkan Anda mengalokasikan lebih banyak. Saat itu Anda telah menghabiskan banyak ruang memori virtual untuk data piksel dalam bitmap. Disimpan dalam memori yang tidak dikelola, pengumpul sampah tidak menyadarinya. Ruang VM yang tidak dapat dilepaskan kecuali Anda memanggil Dispose() atau pengumpul sampah akan menanganinya dengan menjalankan finalizer.

GC biasanya tidak menyelesaikan pekerjaannya, kelas Bitmap adalah objek yang sangat kecil, tidak cukup besar untuk memicu GC dengan sendirinya. Anda harus mengalokasikan sekitar 60.000 di antaranya untuk memicu GC. Anda tidak akan pernah sampai di sana, Anda akan kehabisan ruang VM terlebih dahulu kecuali bitmapnya sangat kecil, selanjutnya ditangani. Memanggil Dispose() bersifat opsional, namun tidak lagi bersifat opsional untuk bitmap karena finalizer tidak dapat menyelesaikan pekerjaannya tepat waktu.

Jumlah RAM tidak berperan dalam hal ini apa pun, program .NET selalu gagal karena tidak dapat menemukan lubang di ruang alamat VM yang cukup besar untuk memenuhi ukuran yang diminta. Juga masalah dengan bitmap, mereka cenderung membutuhkan lubang besar. Hanya dibutuhkan DLL yang dimuat di alamat dasar yang aneh untuk memotong lubang besar menjadi dua. Jika tidak, masalahnya mudah diselesaikan, cukup atur platform target program ke AnyCPU. Program pengujian memiliki nilai konfigurasi untuk itu. Bekerja pada mesin Win7 itu. Namun tentu saja, itu bukan alasan yang sah untuk melewatkan panggilan Dispose().

person Hans Passant    schedule 30.09.2013