Aspnetcore: Asp.net Core tidak Mengumpulkan Sampah

Dibuat pada 21 Mar 2017  ·  136Komentar  ·  Sumber: dotnet/aspnetcore

Saya tidak mengerti mengapa inti Asp.net sepertinya tidak mengumpulkan sampah. Minggu lalu saya membiarkan layanan web berjalan selama beberapa hari, dan penggunaan memori saya mencapai 20GB. GC tampaknya tidak berfungsi dengan baik. Jadi untuk menguji ini saya menulis metode web yang sangat sederhana yang mengembalikan banyak koleksi string. Aplikasi ini awalnya hanya menggunakan 124MB, tetapi setiap kali saya memanggil metode web, penggunaan memori terus meningkat dan semakin tinggi hingga mencapai 411MB. Itu akan menjadi lebih tinggi jika saya terus memanggil metode web. Tetapi saya memutuskan untuk berhenti menguji.

Kode pengujian saya adalah ini:

`

[HttpDapatkan]
Tugas asinkron publik> TesGC() {
const string pesan = "UJI";
return Enumerable.Ulangi(pesan, 100000000);
}
`

Meskipun saya mungkin mengabaikan sesuatu... Untuk pemahaman saya, penggunaan memori tidak boleh meningkat dengan setiap panggilan ke metode ini. Setelah objek dibuat dan dikirim ke UI, memori seharusnya sudah dibebaskan.

Seperti yang Anda lihat dari tangkapan layar di bawah, bahkan setelah GC dipanggil, memori tidak dilepaskan.
netcorescreenshot

Terima kasih untuk bantuannya!
Jay

investigate

Komentar yang paling membantu

Ada berita tentang ini? Saya menggunakan Core 2 melalui Net Framework dan ini masih terjadi. Setiap panggilan ke _Controller_ menambah memori yang digunakan, tetapi tidak pernah turun. (_Saya menggunakan Template WebApi_)

Semua 136 komentar

@rynowak

Meskipun saya mungkin mengabaikan sesuatu... Untuk pemahaman saya, penggunaan memori tidak boleh meningkat dengan setiap panggilan ke metode ini. Setelah objek dibuat dan dikirim ke UI, memori seharusnya sudah dibebaskan.

Tumpukan objek besar kemungkinan menggigit Anda di sini. Jika Anda mengalokasikan objek berukuran > 85KB maka itu akan dimasukkan ke dalam LOH dan sangat jarang dipadatkan . Lihat http://stackoverflow.com/questions/8951836/why-large-object-heap-and-why-do-we-care untuk detail lebih lanjut (atau https://github.com/dotnet/coreclr/blob/master /Documentation/botr/garbage-collection.md#design-of-allocator jika Anda ingin masuk lebih dalam).

Saya tidak mengerti mengapa inti Asp.net sepertinya tidak mengumpulkan sampah. Minggu lalu saya membiarkan layanan web berjalan selama beberapa hari, dan penggunaan memori saya mencapai 20GB

Apa yang dilakukan layanan Anda sehingga membuat objek sebesar itu? Anda harus mencoba mengambil dump memori sebelum menjadi terlalu besar, yang akan dengan jelas menunjukkan kepada Anda objek apa yang menempel dan mengapa itu ditahan (Anda dapat menggunakan studio visual untuk melihat dump atau alat yang lebih canggih seperti windbg atau perfview).

Cobalah untuk mengalokasikan array dari awal daripada memanggil Enumerable.Repeat
atau padatkan memori menggunakan GCSettings.LargeObjectHeapCompactionMode (didukung dalam .Net Standard)

Terima kasih @davidfowl dan @MhAllan atas jawabannya. Tapi contoh ini adalah salah satu yang dibuat-buat. Saya hanya menginginkan sesuatu yang akan menggunakan banyak memori sehingga saya dapat mengambil tangkapan layar. Yang benar adalah bahwa ini terjadi dengan aplikasi apa pun terlepas dari ukuran objek yang dimaksud. Dan untuk menjawab pertanyaan Anda @davidfowl , layanan saya hanya menarik beberapa data dari database dengan rapi, dan mengembalikan objek yang dihasilkan. Itu adalah satu baris data untuk setiap panggilan. Jadi butuh beberapa hari untuk memori tumbuh ke jumlah itu. Saya sebenarnya mencoba menguji DB ketika saya menemukan keanehan ini. Saya telah menulis aplikasi konsol kecil untuk terus memanggil metode ini berulang kali.

@zorthgo yakin itu bukan Dapper? Jika Anda membuat skrip Anda dengan menyuntikkan parameter langsung ke skrip SQL Anda seperti di PHP, Anda akan mendapatkan banyak skrip SQL yang di-cache. Begini cara Dapper melakukannya
https://github.com/StackExchange/Dapper/blob/fe5c270aceab362c93645607a830e6fe1603cac/Dapper/SqlMapper.cs
Anda harus menggunakan profiler memori untuk memberi tahu apa yang menyimpan referensi ke memori yang dialokasikan. Visual Studio 2017 seharusnya dapat membantu Anda mengambil beberapa snapshot dari memori sebelum dan sesudah beberapa panggilan ke aplikasi Anda dan membandingkannya.

@zorthgo Ya saya juga melihat ini. Menggunakan servicestack di aplikasi konsol inti .net saya dan setiap kali saya melakukan panggilan ke api, penggunaan memori meningkat dalam jumlah besar 50mb. Saya berasumsi itu adalah bug VS2017 tetapi kemudian mengkonfirmasi penggunaan yang tinggi di task manager. Seperti yang dinyatakan zorthgo dengan hanya membuat panggilan sederhana ke api, penggunaan memori meningkat secara signifikan dan sepertinya tidak melepaskan memori.

Apakah ini hanya terjadi pada ASP.NET Core di .NET Core atau juga Masalah dengan ASP.NET Core di .NET Framework?

Bisakah Anda menulis aplikasi serupa menggunakan MVC 5 (di System.Web) dan memverifikasi bahwa Anda tidak melihat perilaku yang sama?

Saya tidak dapat membuat kemajuan apa pun dari masalah ini dalam kondisi saat ini.

Dalam contoh saya, saya hanya menggunakan kerangka kerja target .NetCoreApp 1.1 dan aplikasi konsol saya merujuk model objek dalam proyek bersama.

Tidak yakin apakah ini akan membantu siapa pun. contoh aplikasi yang memanggil hellorequest. Dalam aplikasi ini memori startup adalah 85mb, kemudian dengan permintaan berulang saya berhasil mendorong penggunaan memori menjadi sekitar 145mb. Kadang-kadang jatuh kembali ke 125mb tetapi kemudian tetap di sana. Tidak yakin apakah ini perilaku normal karena saya tidak terbiasa dengan aplikasi konsol .Net Core. saya selalu berasumsi saya melakukan sesuatu yang salah atau tidak membuat instance dengan benar.

https://drive.google.com/open?id=0B0Gm-m-z_U84TU5keWFTMzc1ZWc

Menghadapi masalah yang sama di sini pada aplikasi Asp.Net Core yang digunakan untuk produksi dengan 3000-5000 pengguna aktif..memori di server meningkat menjadi 15GB kemarin...saya harus mengonfigurasi IIS untuk mendaur ulang AppPool setiap 3 jam saat saya masih coba cari tahu apa masalahnya.

Apakah ada yang mengambil dump memori dan melihat apa yang mengambil semua memori dalam aplikasi khusus Anda?

@davidfowl @Pinox
Saya bekerja di perusahaan besar, dan kami ingin memulai proyek baru dengan ASP.NET Core, Tetapi ketika saya melihat masalah ini, saya takut :khawatir: . ini adalah masalah kritis dan dapat memblokir siklus hidup proyek kami.

Jadi tolong, apakah ini terkait dengan ASP.NET Core atau .NET Core (CoreCLR)? kami akan menargetkan Full .NET (4.6) itu sebabnya saya bertanya.

@ikourfaln dalam kasus saya, saya menggunakan .net core console app , servicestack (.net core version) dan kestrel. Yang aneh adalah penggunaan memori naik ke level , kemudian berhenti tiba-tiba dan tidak naik lagi. Saya kira yang terbaik adalah mengujinya di pihak Anda dengan sampel kecil dan memeriksa perilaku.

Mungkin @zorthgo dapat memeriksa di sisinya jika dia melihat perilaku serupa dalam memori itu digunakan ke tingkat tertentu dan kemudian berhenti meningkat karena itulah perilaku yang saya lihat. Saya telah memperbarui aplikasi sampel saya untuk menyertakan contoh @zorthgo dan saya tidak melihat memorinya habis. Naik tapi akhirnya berhenti.

Saya memang mengubah sumbernya sedikit:

objek publik Apa saja (permintaan TestGC)
{
const string pesan = "UJI";
return Enumerable.Ulangi(pesan, 100000);
}

@pinox
Terima kasih, saya akan memeriksa perilaku di sisi saya.

Bagaimana dengan bug ini di 2.0?

Ada berita tentang ini? Saya menggunakan Core 2 melalui Net Framework dan ini masih terjadi. Setiap panggilan ke _Controller_ menambah memori yang digunakan, tetapi tidak pernah turun. (_Saya menggunakan Template WebApi_)

Hai,

Saya memiliki masalah yang sama dengan ASP.NET Core 2. Saya telah mengambil dump memori dan mencoba menganalisis. Dari apa yang saya lihat masalahnya persis seperti yang dikatakan OP. Aplikasi saya dimulai dengan alokasi sekitar 75 MB, dan sangat cepat hingga ~750MB, darinya 608MB adalah "Memori yang tidak digunakan dialokasikan ke .NET".

Cuplikan pertama saat aplikasi dimulai:
image

Cuplikan kedua setelah 3 menit dan 100 permintaan:
image

kami juga menghadapi masalah yang sama, pengontrol kami berurusan dengan sejumlah besar data, (yang merupakan desain yang buruk dan akan segera diganti), setiap panggilan ke pengontrol ini menyebabkan memori bertambah. Memori berkurang tetapi hanya 40-50% (mendapatkan 50 Mb, mengurangi 30-35 Mb), setiap panggilan meningkatkan memori dalam kisaran 10-15 Mb setiap kali. Layanan di-host di dalam struktur layanan.

Sepertinya saya memiliki masalah serupa di layanan produksi kami (20-100 req/s) menggunakan kombinasi:

  • ASP.NET Inti 2.0.4
  • ServiceStack.Core 1.0.44
  • SkiaSharp 1.59.2
  • Docker v17.09.0-ce, buat afdb6d4 di Ubuntu 16.04 x64
  • server x4 @ 40 CPU, memori 128 GB
  • Server GC benar
  • setiap wadah Docker diatur ke pembagian cpu 12k (mhz), ram 8GB

Aplikasi ini memiliki server web dan pekerja front-end (masing-masing ditunjukkan pada grafik di bawah).

server web (6 jam terakhir)
screen shot 2018-01-13 at 1 06 24 pm

pekerja (6 jam terakhir)
screen shot 2018-01-13 at 1 07 55 pm

Keduanya menggunakan array byte besar karena layanan bertindak sebagai proxy penyimpanan objek, dan akibatnya menempatkan objek di LOH. Pertanyaan saya adalah, apakah ini batasan yang diketahui dari .NET Core saat ini? Sepertinya LOH di tidak pernah sepenuhnya dibersihkan atau terfragmentasi.

Karena itu, SOH tampaknya berfungsi dengan baik, karena objek api web biasa dibersihkan. Ada saran? Apakah ada masalah dengan pengaturan saya? Saya telah menganalisis kode dan tidak dapat menemukan kebocoran memori yang mencolok, dan saya tidak menggunakan sesuatu yang istimewa di luar perpustakaan ServiceStack.

@sebastienros - ada pemikiran tentang ini? Sudahkah kita mengamati perilaku serupa di sistem kita?

  • Kami hanya mengukur ini pada 2.1, saya akan menambahkan hal yang sama untuk 2.0
  • Semua komentar tampaknya terkait dengan masalah LOH yang disebutkan, yang harus diperhitungkan dalam aplikasi dan mengumpulkan array besar sebanyak mungkin

@sebastienros , beberapa pertanyaan:

  1. Saya menggunakan Ants profiler untuk mengukur penggunaan memori, menurutnya tidak ada fragmentasi LOH yang terdeteksi. Bisakah Anda memberi tahu bagaimana saya bisa memverifikasi jika aplikasi saya mengalami masalah fragmentasi LOH?
  2. Apa hasil di .net core 2.1? Apakah masalah teratasi karena Kestrel menggunakan Span?
  3. Bagaimana jika kami tidak dapat menggabungkan array - dapatkah Anda memberikan solusi? Haruskah kita menggunakan GCSettings.LargeObjectHeapCompactionMode.CompactOnce?

Apa hasil di .net core 2.1? Apakah masalah teratasi karena Kestrel menggunakan Span?

Kami pribadi belum melihat bukti bahwa masalahnya ada di Kestrel. Masih terlihat seperti masalah aplikasi.

Bagaimana jika kami tidak dapat menggabungkan array - dapatkah Anda memberikan solusi? Haruskah kita menggunakan GCSettings.LargeObjectHeapCompactionMode.CompactOnce?

@jkotas @Maoni0 Ada saran di sini?

bagaimana saya bisa menyelidiki jika saya mengalami masalah yang sama? LOH menurut profiler memori redgate hampir kosong seperti yang dijelaskan @sinapis tetapi masih menggunakan lebih dari 1gb untuk hanya satu pengguna

Kumpulkan jejak dan analisis menggunakan perfview. Ada sejumlah tutorial oleh Vance dan yang lainnya tentang cara melacak kebocoran memori .NET: https://www.bing.com/search?q=.NET%20memory%20leak%20perfview .

https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md memiliki instruksi khusus Linux untuk mengumpulkan jejak.

Jika Anda yakin tidak ada kebocoran memori dan GC hanya menyimpan lebih banyak memori yang Anda inginkan, Anda dapat mencoba:

  • Menggunakan objek pekerjaan Windows atau batas memori wadah buruh pelabuhan untuk membatasi berapa banyak memori yang dapat digunakan proses. GC memperhitungkan batasan-batasan ini dan berjalan lebih agresif saat mendekatinya.
  • Atau, beralih dari Server GC ke Workstation GC. Bukan hal yang aneh jika server GC memiliki set kerja puncak yang jauh lebih tinggi. Workstation memiliki set kerja puncak lebih tinggi yang lebih rendah, tetapi juga throughput yang lebih rendah.

Hai,

Saya pikir saya mengalami masalah yang sama dengan .Net Core Web API dalam produksi.

Aplikasi ini berjalan di Windows Server 2016 dengan .Net Core 2.0.3. Mesinnya adalah VM Hyper-V dengan 28 inti CPU dan RAM 24GB. Jika kita tidak cukup sering mendaur ulang kumpulan aplikasi IIS, pada akhirnya kita akan menggunakan semua memori yang tersedia. Saat aplikasi mulai menggunakan banyak memori (>=95% dari total memori sistem) penggunaan CPU juga meningkat pesat (kadang-kadang dari 2% menjadi 70%). Saya tidak yakin apakah pengecualian OOM dipicu atau tidak, kami selalu mendaur ulang kumpulan sebelum itu terjadi (penggunaan memori maksimum yang saya lihat adalah 98% dari memori yang digunakan oleh dotnet.exe).

Menganalisis dump memori produksi dengan ".Net Memory Porfiler" (Perangkat Lunak SciTech) inilah yang saya temukan:
image

Jika analisis ini benar, sekitar 95% memori berada di "overhead > unused". Inilah cara editor profiler memori ini menjelaskan kategori ini (di forum mereka):
_"Overhead->Unused" adalah memori yang dilakukan oleh runtime .NET untuk tumpukan terkelola. Saat ini tidak digunakan, tetapi tersedia untuk alokasi instans di masa mendatang. Ada banyak aturan yang digunakan runtime untuk memutuskan apakah akan menyimpan memori yang dikomit atau melepaskannya ke OS. Itu tergantung pada faktor-faktor seperti memori yang tersedia, pola alokasi, jumlah prosesor, apakah server GC digunakan, dll._

@jkotas Saya akan menerapkan rekomendasi Anda (objek pekerjaan Windows, dan beralih ke workstation GC) dan saya akan memberi tahu Anda hasilnya. Tolong beri tahu saya jika saya dapat mengekstrak informasi berguna lainnya dari dump memori produksi yang saya miliki.

Terima kasih

@sinapis @ronald7
Apakah ada di antara Anda yang dapat membagikan aplikasi yang menunjukkan masalah tersebut? Jika saya dapat mengulanginya, kami akan dapat menemukan alasannya, atau setidaknya menghapus beberapa kode sepotong demi sepotong dan mengisolasi repro minimal.

@sebastienros Saya tidak dapat membagikan aplikasi, tetapi saya dapat membagikan sesi dari PerfView session + memory dump .
Beberapa deskripsi: Saya memiliki ASP.NET Core 2 Web API, saya telah membuat uji beban 200 pengguna yang semuanya mengirim permintaan yang sama selama 10 detik. Secara keseluruhan 775 permintaan diproses.

Aplikasi ini melompat ke hampir 1 GB penggunaan memori di task manager dan tetap seperti itu. Melihat dump saya dapat menghitung sekitar 18 MB:

image

Jadi pertanyaannya adalah kemana perginya hampir 1 GB?

@sinapis Terima kasih

Perilaku yang Anda gambarkan tidak terduga, GC akan mengalokasikan beberapa memori seperlunya pada beban puncak, dan hanya melepaskannya seiring waktu. Ini adalah mode Server GC, dan biasanya menunggu periode idle untuk melepaskannya dan tidak memengaruhi kinerja aplikasi Anda. Jumlah memori yang akan dicadangkan tergantung dari total memori yang tersedia pada sistem.

Kami pasti akan melihat masalah jika terus meningkat. Saya berasumsi bahwa jika Anda tidak mengirim permintaan lagi dan membiarkan aplikasi Anda berjalan, Anda akan melihat penggunaan memori turun.

Bisakah Anda menjalankan hal yang sama hingga menghabiskan sebagian besar memori sistem Anda? Atau setidaknya cukup lama dengan beban yang sama sehingga akan menunjukkan pertumbuhan terus menerus? Saya masih akan melihat kesedihan Anda saat ini.

Anda juga dapat membuang sampah selama dan di akhir pekerjaan, sehingga kami dapat melihat detailnya.

Hai @sebastienros

Sayangnya, saya tidak dapat membagikan aplikasi atau dump memori, tetapi saya akan membuat aplikasi dummy (dengan arsitektur dan dependensi yang sama), menjalankannya di mesin yang sama, jika saya dapat mereproduksi perilaku ini, saya akan membagikan yang ini kepada Anda. Tolong beri tahu saya jika ada informasi berguna yang dapat saya ekstrak untuk Anda dari dump memori.

Saya telah memperbarui mode GC dari _server_ ke _workstation_ di satu server produksi, saya akan memberi tahu Anda dalam beberapa jam dari sekarang jika ada perubahan pada penggunaan memori.

Saya juga melakukan tes lain: kami menjalankan aplikasi kami di belakang penyeimbang beban, pada 4 mesin virtual. Setelah menghapus salah satu mesin dari kumpulan penyeimbang beban, memori yang digunakan oleh dotnet.exe tidak berkurang dan tetap pada tingkat yang sama bahkan setelah 30 menit. (Namun, aplikasi masih memproses beberapa permintaan: satu permintaan dikirim oleh SCOM pada titik akhir dummy setiap 30 detik). Tidak ada memori yang dilepaskan dan dikembalikan ke sistem.

Terima kasih

@sinapis Saya melihat jejak ETW Anda. itu membingungkan bagi saya - Anda bertahan sangat sedikit dalam gen2 GC terakhir yang diinduksi namun kami masih memilih untuk menyimpan banyak memori yang berkomitmen. aplikasi Anda tampaknya kasus tepi (Anda kebanyakan hanya melakukan GC latar belakang karena alokasi LOH) - Saya ingin tahu apakah kami memiliki beberapa kesalahan akuntansi di sana (kemungkinan lain adalah kesalahan dalam angka yang dilaporkan tetapi jika Anda sudah memverifikasi bahwa Anda memiliki komitmen sebanyak itu, itu adalah kemungkinan yang lebih kecil). jika Anda dapat mengulangi sesuatu yang dapat Anda bagikan kepada saya, itu akan luar biasa; jika tidak, jika mungkin untuk menjalankan aplikasi Anda dengan beberapa pencatatan dari GC (saya dapat memberi Anda komit yang melakukan itu) itu juga akan membantu.

@Maoni0 tolong bagikan bagaimana saya harus mengaktifkan GC logging
Jika ada beberapa data lain yang Anda ingin saya berikan untuk menyangkal kesalahan akuntansi, beri tahu saya apa yang harus saya berikan kepada Anda dan bagaimana caranya (mungkin beri tahu perfview untuk mengumpulkan lebih banyak data?)
Saya akan mencoba membuat repro minimum, tetapi tidak yakin saya akan berhasil karena saya tidak tahu di mana masalahnya.

@sebastienros semoga saya akan memberikan dump lain dengan konsumsi memori lebih banyak hari ini

Hai @sebastienros @Maoni0 ,

Saya menjalankan aplikasi kami dengan mode GC workstation selama 12 jam tetapi hasil yang sama. Saya juga mengkompilasi ulang aplikasi dengan .Net 2.1 Preview 2 pada satu node produksi selama 1 jam, saya akan memberi tahu Anda hasilnya, tetapi untuk saat ini prosesnya sudah menggunakan 2GB+ RAM.

image

Saya memiliki PerfView yang berjalan di mesin yang sama ini dan saya mengumpulkan dump GC, apakah ada alamat email tempat saya dapat mengirimi Anda tautan OneDrive, sayangnya saya tidak dapat membagikannya secara langsung di utas ini.

Jika itu dapat membantu, saya juga dapat mengumpulkan lebih banyak metrik atau log GC. Terima kasih

@ronald7 _redacted_ Saya bisa meneruskan ke @Maoni0

Hai @sebastienros @Maoni0 Saya baru saja mengirimi Anda email dengan dua gcdump PerfView dan file VMMap, saya harap ini bisa membantu. Di pihak saya, saya masih mencoba mereproduksi perilaku penggunaan memori tinggi ini dengan aplikasi dummy.

Terima kasih!

Saya juga mengalami masalah yang sama. Pengumpulan sampah tidak pernah terjadi! Tangkapan layar menunjukkan penggunaan memori setelah melakukan sekitar 50 permintaan menggunakan aplikasi dotnet core web api yang cukup sederhana.

memory-profile2

Saya baru saja memutakhirkan aplikasi ASP.NET Core yang berjalan di Ubuntu 16.04 dari 1.1 ke 2.0 dan mengalami masalah ini. Ini cukup parah, menyebabkan kernel sering mematikan aplikasi karena kesalahan OOM, dan saya mempertimbangkan apakah akan menurunkan versi kembali ke 1.x. Ada halaman tertentu yang tidak dapat kami muat sama sekali - bahkan setelah Kestrel dimulai ulang, aplikasi segera menghabiskan memori yang tersedia setelah satu permintaan! Saya berpikir untuk memutakhirkan server, tetapi berdasarkan komentar di sini tentang aplikasi ASP.NET Core menggunakan semua memori yang tersedia, saya tidak berharap itu akan membantu. Tumpukan kami pada dasarnya adalah ASP.NET MVC Core + EF Core ... tidak ada yang terlalu mewah. Jika saya punya waktu, saya akan mencoba membuat sampel untuk mereproduksi masalah - saya tidak berpikir itu akan sesulit itu, mengingat kesederhanaan tumpukan kami.

FWIW, sistem yang saya tingkatkan juga memiliki aplikasi konsol .NET Core, dan tampaknya tidak ada masalah memori setelah pemutakhiran 2.0, jadi ini jelas merupakan masalah terkait ASP.NET Core.

@danports sudahkah Anda mencoba memanggil GC.Collect() melihat apakah penggunaan memori turun drastis? yang akan memberi kita petunjuk di mana kita harus mulai. jika GC.Collect() (atau GC.Collect/GC.WaitingForPendingFinalizers/GC.Collect sequent) tidak dapat membuat penggunaan memori turun secara dramatis, itu berarti ada banyak memori yang perlu dihidupkan sehingga GC tidak dapat mengklaimnya kembali.

@Maoni0 Saya belum mencobanya. Saya tidak berpikir masalah saya adalah dengan GC, karena saya memang melihat penggunaan memori menurun dari waktu ke waktu - sepertinya aplikasi .NET Core 2.0 saya menghabiskan kira-kira 2-3x memori yang mereka lakukan dibandingkan ketika mereka berjalan di .NET Core 2.0. Inti bersih 1.1.

Saya menurunkan kembali ke .NET Core 1.1 untuk saat ini dan akan mengunjungi lagi nanti ketika saya punya lebih banyak waktu, mungkin setelah .NET Core 2.1 dirilis. (Saya mengalami setumpuk masalah dengan 2.0 dan ini hanya salah satunya.)

GC.Collect() tidak membantu. Mencoba ASP.NET Core 2.0 dan 2.1 Web API yang sangat sederhana yang memiliki satu pengontrol yang mengembalikan kamus 200k int. Memori yang dialokasikan terus meningkat dengan setiap permintaan, meskipun aplikasi tidak menggunakan memori lagi.

@Serjster mengembalikan 200K bilangan bulat (4B) akan membutuhkan 800KB. Dalam hal ini Anda mengalami masalah yang dijelaskan dalam komentar ini: https://github.com/aspnet/Home/issues/1976#issuecomment -289336916

Dalam hal ini Anda harus menggunakan kumpulan array untuk menggunakannya kembali di seluruh permintaan.

Juga baik untuk diketahui adalah bahwa jika kode berjalan dalam mode 64bit maka array/daftar dll. yang berisi pointer berukuran dua kali lipat dibandingkan dengan 32bit. Jika saya ingat dengan benar kerangka kerja penuh menjalankan kode cpu 32bit di OS 64bit secara default. Jadi orang yang memigrasikan kode mereka mungkin secara tidak sengaja mengalami masalah LOH.

Saya bekerja dengan @Serjster , dan inilah yang saya temukan. Jika saya membuat proyek vanilla web api menggunakan asp.net core (saya menggunakan 2.1 dalam pengujian terbaru saya), saya perhatikan bahwa ketika saya menjalankan alat diagnostik (atau bahkan memeriksa proses memori yang diatur dalam kode), jumlah byte kembali terus mendaki saat saya mencapai titik akhir. Misalnya, jika saya memiliki satu titik akhir api web yang mengembalikan Kamusdengan 20.000 item di dalamnya, berikut ini terjadi:

  1. Kunjungan pertama ke metode pengontrol menempatkan Memori Proses pada 83MB.
  2. Saya tunggu beberapa detik, dan kunjungan kedua itu pindah ke 86MB.
  3. Saya menunggu beberapa detik, dan kunjungan ketiga pindah ke 90MB.
  4. Sekali lagi - 94MB.
  5. Saya melakukan ini beberapa kali, dan akhirnya mencapai sekitar 304MB. Setelah melakukan ini, levelnya turun.

Jika objek yang dikembalikan adalah objek berukuran berbeda, semua angka di atas hanya lebih besar/lebih kecil (termasuk jumlah level off), tetapi pola pertumbuhannya sama (alias akan tumbuh dan bertambah hingga levelnya turun setelah banyak permintaan) .

Jika saya menambahkan GC.Collect dalam pemanggilan metode (jadi itu terjadi pada setiap permintaan, levelnya jauh lebih rendah, tetapi masih ada periode pertumbuhan hingga levelnya turun.

Poin detail menarik lainnya adalah jumlah objek dan ukuran tumpukan saat melakukan snapshot sebagian besar tidak berubah pada setiap kunjungan. Tetapi grafik Memori Proses terus menunjukkan angka yang lebih tinggi dan lebih tinggi (ini juga berlaku jika Anda mengambil proses dan menarik nilai set memori yang berfungsi).

Saya mulai curiga bahwa grafik menunjukkan memori yang dialokasikan (dan memori ini tumbuh berdasarkan beberapa penggunaan inti asp.net/logika peramalan permintaan), tetapi ini belum tentu dikonsumsi/membocorkan memori. Saya tidak cukup tahu untuk mengonfirmasi, jadi bertanya-tanya apakah seseorang yang lebih berpengetahuan mungkin dapat bergabung.

EDIT - komentar @davidfowl : Mengenai komentar Anda tentang hal-hal yang jarang dikumpulkan ... ini bisa masuk akal. Tapi biasanya butuh waktu berapa lama? Saya bisa pergi 30+ detik di antara permintaan, dan GC sepertinya tidak pernah menurunkan nomor memori itu di bagan diagnostik. Saya yakin saya tidak tahu apa-apa di sini, tetapi hanya ingin tahu.

EDIT 2 - Sekarang saya telah membaca tautan SO yang diposting david di atas secara lebih rinci, saya mulai berpikir ini pasti masalah yang kita lihat. Jika kita berjalan di lingkungan dengan memori terbatas (di mana kita berada di lingkungan pengembang kita di mana kita melihat ini karena kita murah), kita mengalami masalah dengan ini.

Sunting 3 - Satu pertanyaan yang tersisa. Mengapa memori proses naik secara konsisten, tetapi ukuran tumpukan tidak naik jika ini adalah masalah LOH? Sebenarnya, saya mungkin mengerti ini sekarang. Heap adalah memori yang digunakan. Memori yang dialokasikan prosesor adalah memori yang digunakan ditambah blok memori terfragmentasi yang tidak digunakan.

@RemyArmstro dapatkah Anda mengubah Dictionary<int, int> menjadi SortedDictionary<int, int> ? Kamus mungkin mengalokasikan memori berkelanjutan, bahkan mungkin menambahkan beberapa data tambahan ke setiap entri. Cara SortedDictionary diimplementasikan akan membuat banyak alokasi kecil alih-alih satu alokasi besar.

Sunting: Jika Anda membuat serial ke string dan tidak langsung ke Stream keluaran respons maka itu mungkin juga menyebabkan alokasi LOH.

@wanton7 Tanggapan Anda tidak ada intinya. Kamus hanyalah puncak gunung es. Kita dapat menggunakan daftar, array, dll dll dan mereka semua melakukan hal yang sama. Namun, seperti yang ditunjukkan jika LOH yang menyebabkan ini, seperti yang terdengar, maka perilaku ini mungkin baik-baik saja? Kecuali ini mungkin memiliki beberapa efek samping yang mengkhawatirkan, seperti apa yang terjadi ketika Anda kehabisan memori? Apakah aplikasi Anda baru saja crash?

@Serjster ok saya pikir Anda hanya memiliki kasus kecil di mana ini terjadi. Bagi saya sangat tidak biasa memiliki daftar besar, array seperti ini dan mengirimkan data sebanyak ini dalam satu panggilan api jika bukan biner. Biasanya ketika Anda memiliki semacam web api dan mendapatkan beberapa data darinya, Anda menggunakan paging. Anda seharusnya tidak mengirim 10.000 entri ke sisi klien.
Tetapi jika Anda memiliki banyak masalah seperti ini dan tidak ada cara untuk mengubah cara kerja api Anda, maka saya pikir Anda harus membuat implementasi Daftar dan Kamus Anda sendiri. Jika Anda benar-benar menggunakan array sebesar ini maka Anda dapat menggantinya dengan daftar potongan Anda atau mencoba menggabungkannya saat aplikasi dimulai.

Saya berharap Microsoft akan membuat implementasi chunked yang dapat digunakan semua orang dalam situasi seperti ini.

@wanton7 sekali lagi Anda tidak mengerti maksudnya. Tidak masalah ukuran daftar. Bahkan satu item atau daftar kecil menyebabkan masalah ini terjadi.

@Serjster mungkin saya hanya buta tetapi saya tidak melihat posting apa pun dari Anda di mana Anda mengatakan mengirim satu item atau daftar kecil akan menyebabkan ini terjadi. Apakah Anda menghapusnya?

Atau dari @RemyArmstro Dia berbicara tentang kamus berukuran berbeda. Saya memeriksa corefx dan Kamus akan mengalokasikan array atau ini

private struct Entry
{
  public int hashCode;    // Lower 31 bits of hash code, -1 if unused
  public int next;        // Index of next entry, -1 if last
  public TKey key;           // Key of entry
  public TValue value;         // Value of entry
}

Alokasi 85000 byte akan menyebabkan alokasi LOH sehingga Kamus dengan kapasitas 5313 entri kunci int dan nilai int akan menyebabkan alokasi LOH. Kapasitas tidak sama dengan angka atau entri, kapasitas tampaknya diperluas dengan bilangan prima, periksa metode Resize pribadi Kamus pribadi. Setiap struct dapat memiliki alokasi ekstra ditambah bantalan memori sehingga entri yang lebih rendah dapat menyebabkan alokasi LOH.

Detail implementasi kamus Dictionary.cs

Sunting: url tetap

@wanton7 Terima kasih. Saya pikir kita menyadari apa masalahnya sekarang. Ini hanya mengecewakan tidak ada solusi yang bagus + sederhana untuk ini. Ini pada dasarnya turun untuk menjadi lebih sadar akan hal itu dan menyesuaikan cara Anda menulis kode. Kelemahannya adalah memori yang tidak terkelola ini mulai terasa sedikit lebih terkelola. :( Pada akhirnya, kami mungkin hanya memiliki beberapa area yang benar-benar melanggar batas alokasi ini, tetapi salah satu area cukup inti untuk aplikasi kami, jadi kami sering melihatnya saat ini. Saya pikir kami hanya perlu memikirkan kembali bagian itu, pantau, dan coba temukan area lain yang kami perhatikan merayap ini. Terima kasih lagi!

Kami sebenarnya memiliki situasi yang sama segera dan kami perlu membuat implementasi IList<T> chunked. Saya akan menggunakan beberapa ukuran untuk potongan yang bitshiftable jadi saya bisa menggunakan bitshift dan mask untuk pengindeksan.

Saya ingin tahu mana yang lebih bermanfaat untuk GC, potongan yang lebih besar atau potongan yang lebih kecil? Dari ukuran antara 1KB dan 64KB. Potongan yang lebih kecil berarti lebih banyak referensi untuk GC tetapi saya kira potongan yang lebih besar mungkin lebih buruk untuk pemadatan dan fragmentasi.

pemahaman Anda tepat - saya akan memilih ukuran yang tidak terlalu besar; mungkin coba 4k/8k.

@Maoni0 terima kasih!

Saya memilih 4KB, sehingga kami tidak mendapatkan kejutan buruk jika kami menjalankan kode kami di bawah Mono. Ditemukan dengan membaca http://www.mono-project.com/docs/advanced/garbage-collector/sgen/working-with-sgen/ bahwa ambang batas LOH hanya 8000 byte di bawah Mono.

Apakah ada kemajuan untuk masalah ini?

Kami mengamati masalah yang sama di mana memori proses terus bertambah meskipun ukuran tumpukan tetap sama (atau menurun).

@sebastienros dapatkah Anda melihat ini lagi? Mungkin kami dapat memberikan beberapa petunjuk terperinci untuk membantu orang menyelidiki skenario mereka lebih lanjut?

Berikut adalah beberapa item yang perlu dipertimbangkan dengan situasi kami:

  • Kami hanya mengembalikan objek Dictionary<int, int> dengan 1000 nilai integer yang disimpan. Tidak lebih dari itu.
  • Kami mengonversi proyek kami dari .NET Core 2.0 --> 2.1
  • Kami melihat masalah ini di MS Visual Studio 2017

Kode sebagai berikut:

    public async Task<IActionResult> SampleAction()
    {
        var list = new Dictionary<int, int>();
        for (int n = 0; n < 1000; n++) list.Add(n, n);
        return Ok(list);
    }

Untuk mereproduksi Anda harus mensimulasikan beberapa bentuk beban sedang. Kami baru saja mengklik dengan cepat menggunakan Postman dan dapat mengamati perilaku ini. Setelah kami berhenti mensimulasikan beban, kami melihat ukuran tumpukan berkurang namun memori proses tetap sama (bahkan ketika kami memaksa GC).

Saya melihat ini juga di salah satu proyek saya, tetapi saya juga dapat membuatnya kembali di .net core API baru yang menargetkan .Net Core 2.1 (SDK 2.1.302).

Saya melampirkan contoh proyek API yang saya buat menggunakan Visual Studio 15.8.0 Pratinjau 4. Untuk menunjukkan peningkatan memori, saya memiliki aplikasi konsol inti .net yang mencapai nilai default GET endpoint setiap setengah detik untuk mendapatkan 2 string. Proses penggunaan memori lambat tetapi dalam proyek yang mengembalikan lebih banyak data, ini dapat berkembang dengan cepat.

screenshot
Aplikasi Web1.zip

Saya menemukan posting ini di pertukaran tumpukan:

https://stackoverflow.com/questions/48301031/why-doesnt-garbage-collector-in-net-core-2-0-free-all-memory

Adakah yang membuat profil aplikasi mereka dalam mode rilis untuk melihat apakah perilaku ini ada? Saya akan mencobanya hari ini dan melihat apakah masalah tetap ada.

Sunting : Saya mencoba membuat profil dalam mode Rilis dan masalah masih berlanjut. Saya bahkan memaksa GC untuk melihat apakah itu akan berpengaruh.

image

@chrisaliotta terima kasih telah menautkan ke pos itu, saya tidak mengetahui perilaku itu. Memang akan menarik untuk melihat apakah itu menjelaskan apa yang dilihat orang.

@Eilon @chrisaliotta Terima kasih tapi ini tidak terkait dengan diskusi ini. .NET tidak melepaskan memori dalam mode debug adalah perilaku yang terkenal dan inilah mengapa kami hanya mengukur konsumsi memori (dan potensi kebocoran) dalam mode rilis. Bahkan pada mode rilis, Anda akan melihat peningkatan memori hingga batas waktu tertentu karena mode Server GC. Jadi contoh ini tidak membuktikan apa pun karena dua alasan berbeda.

@sebastienros Jadi, apakah perilaku yang saya dan @beef3333 amati konsisten dengan apa yang diharapkan? Yaitu, di mana Private Bytes tetap meningkat meskipun ukuran tumpukan berkurang? Jika demikian, tampaknya aneh bagi saya bahwa setiap permintaan tambahan akan terus menyebabkan byte pribadi bertambah meskipun ada ruang heap kosong.

Dalam mode Debug ya. Jadi silakan coba gunakan mode Rilis, dan jalankan stres Anda untuk waktu yang lama. Jika memori meningkat tanpa batas maka ada kebocoran memori. Jika memori didaur ulang (bahkan jika itu membutuhkan sejumlah besar memori) maka semuanya baik-baik saja dalam kasus Anda.

Saya baru saja mengujinya lagi menggunakan proyek yang sama yang saya lampirkan dalam mode Rilis dan saya melihat perilaku yang sama persis.

Saya akan menguji aplikasi Anda, terima kasih.

Saya menjalankan aplikasi yang disediakan oleh @beef3333 secara lokal selama 2 jam, dengan kecepatan 5K RPS, dan memorinya stabil (bervariasi 1MB secara keseluruhan, pada 400MB pada mesin dengan 32GB). GC benar disebut teratur. Saya juga memeriksa beberapa dump dari waktu ke waktu dan berbagai contoh dibuat dan dikumpulkan seperti yang diharapkan. Saya menggunakan 2.1.1.

@sebastienros Terima kasih telah memeriksa ini. Saya pikir takeaway dalam semua ini adalah bahwa:

  • Manajemen memori akan berperilaku berbeda untuk aplikasi web .NET Core versus aplikasi desktop biasa Anda.
  • Pengembang harus fokus pada konsumsi memori rata-rata sebagai permintaan fungsi per detik (RPS) selama periode waktu tertentu.
  • Pertumbuhan byte pribadi mungkin tidak selalu menunjukkan kebocoran memori.

Perbaiki saya jika saya salah, tetapi tampaknya .NET Core akan menambah memori yang dialokasikan berdasarkan permintaan rata-rata untuk memastikan waktu respons tercepat? Jika benar, apakah aman untuk mengasumsikan bahwa kemungkinan tidak akan melepaskan memori yang dialokasikan ini hingga Kumpulan Aplikasi direset -- atau akankah ia melepaskan memori yang dialokasikan ini seiring waktu jika RPS menurun?

Masalah yang sama.
Saya memiliki layanan backend webapi asp.net.
Tumpukannya adalah asp.net mvc, autofac, automapper, castle.dynamicproxy, inti kerangka entitas.
Semua memori akan dimakan, lalu layanan macet.

Versi 2.1.0

@atpyk Perbarui ke 2.1.1. Jika itu tidak membantu, Anda harus benar-benar membuat profil apa yang menyimpan memori itu. Saya telah menggunakan https://www.jetbrains.com/dotmemory/ tetapi mungkin ada alat lain yang dapat melakukan ini juga. Itu dapat menunjukkan apa yang sebenarnya dialokasikan di Large Object Heap (LOH).

Apakah Anda menjalankan dalam mode 32bit? Karena alokasi Heap Objek Besar (lebih besar dari ~85000 byte) dapat menyebabkan pengecualian memori dalam mode 32bit karena fragmentasi. Anda dapat melewati batas ini dengan sangat mudah menggunakan Kamus. Periksa komentar ini https://github.com/aspnet/Home/issues/1976#issuecomment -393833505

Jika Anda menjalankan kode Anda secara penuh, perilaku default .Net Framework adalah menjalankan kode cpu apa pun dalam mode 32bit. Anda perlu menghapus centang Pilih 32bit dari pengaturan proyek atau atur beberapa pengaturan registri di registri server Anda ke default ke 64bit.

@wanton7 Terima kasih banyak. Saya akan mencoba solusi Anda.

Saya memperbarui ke 2.1.2 dan menggunakan aplikasi web Microsoft Azure dengan win-x64, tetapi tidak berpengaruh. @wanton7
dotnetcorememory

@atpyk tolong buat snapshot memori (dump_ dan analisis (Visual Studio, MemoScope) untuk melihat objek apa yang mengambil semua memori, atau hanya bertambah jumlahnya. Anda juga dapat mengambil dua dan membandingkannya dari waktu ke waktu.

@sabastienros Saya percaya bahwa cukup banyak orang telah menyampaikan kekhawatiran tentang hal ini sehingga Anda/MS harus benar-benar mulai menganalisis ini sendiri. Mungkin ini berfungsi seperti yang Anda inginkan, tetapi desainnya cacat.

Aplikasi kami akhirnya kehabisan memori dan mogok, dan ini semua berjalan di lingkungan produksi Azure. Ini tidak bisa di terima.

@atpyk maka kedengarannya seperti kebocoran memori. Profil memori Anda untuk melihat apa yang menyimpan memori itu seperti yang dikatakan @sebastienros .

Satu pertanyaan, apakah Anda bahkan menggunakan ASP.NET Core? Saya membaca komentar pertama Anda lagi dan Anda menyebutkan ASP.NET MVC. ASP.NET MVC dan ASP.NET Core adalah dua produk yang sama sekali berbeda. Masalah ini dan repo ini untuk ASP..NET Core.

Sunting: Hanya dari nomor versi terdengar seperti Anda menggunakan ASP.NET Core, tetapi ingin memastikan.

Kami menggunakan .net core MVC. @wanton7
Saya melakukan analisis memori. Mungkin Proxy Dinamis Castle menyebabkan kebocoran memori.
memroy1
memroy2
memroy3
dynamicproxy

@Serjster apakah program Anda berjalan dalam 32bit .NET Core dan mogok tanpa pengecualian memori? Jika kode Anda melakukan banyak alokasi LOH maka fragmentasi memori mungkin adalah alasannya.
Jika Anda menjalankan di lingkungan 32bit, Anda memiliki dua pilihan, perbaiki kode Anda untuk menghindari LOH atau beralih ke lingkungan 64bit.

Saya tidak terlalu akrab dengan Azure tetapi setelah sedikit googling menemukan ini https://blogs.msdn.microsoft.com/webdev/2018/01/09/64-bit-asp-net-core-on-Azure-app -melayani/

@Serjster Saya percaya tidak semua laporan di sini sama, dan lebih suka memeriksa validitas setiap kasus yang berbeda. Sesuatu seperti "aplikasi saya memiliki kebocoran memori" tidak berarti itu karena kerangka kerja, jadi saya lebih memilih untuk memastikan setiap kasus itu yang sebenarnya.

Mengambil kasus Anda misalnya, "Saya percaya" bahwa saya menjawab alasan mengapa memori Anda meningkat. Apakah Anda bisa memperbaikinya setelah penjelasan saya? Atau itu tidak menyelesaikan masalah dan dalam hal ini dapatkah Anda memberikan aplikasi yang dapat saya jalankan secara lokal untuk mereproduksi masalah?

@sebastienros Apa yang akhirnya kami temukan adalah bahwa alokasi memori terus meningkat, meskipun konsumsi memori tidak. Saya tahu inti ASP.NET melakukan beberapa heuristik untuk memberi tahu bahwa itu harus mengambil lebih banyak, tetapi tampaknya terus-menerus mengalokasikan lebih banyak dan lebih banyak pada setiap permintaan. Ini hampir tampak serakah bagi saya dalam hal ini, tetapi saya bisa saja salah.

Either way, saya pikir poin @Serjster adalah bahwa utas ini terus berkembang karena jelas ada beberapa kebingungan di sini. Di tanah ASP.NET lama (sebelum inti 1 saya percaya), kami tidak perlu melihat perilaku ini (setidaknya tidak sebesar ini. Ini mungkin bukan bug/masalah, tetapi itu pasti sesuatu yang menyebabkan banyak orang untuk mengajukan pertanyaan yang sama berulang-ulang.

Alangkah baiknya jika ada artikel resmi yang benar-benar membahas utas ini dari atas ke bawah, alih-alih berputar-putar seperti sebelumnya. Semoga membantu memperjelas.

Alangkah baiknya jika ada artikel resmi yang benar-benar membahas utas ini dari atas ke bawah, alih-alih berputar-putar seperti sebelumnya. Semoga membantu memperjelas.

Saya kedua itu. Akan lebih baik bagi kita untuk mengetahui mengapa .NET Core 2.1 lebih "oportunistik" dalam hal manajemen memori daripada versi sebelumnya.

@sebastienros dapatkah kami memiliki ringkasan masalah di sini? ada 81 komentar - saya mendapat kesan bahwa mereka tidak semua tentang masalah (walaupun saya belum membacanya dengan cermat sama sekali jadi saya mungkin salah). jika demikian, dapatkah kami membuat daftar semua masalah yang berbeda di sini dan melihat apakah kami memiliki repro untuk masing-masing masalah? ada cukup banyak orang yang telah menyebutkan peningkatan memori, saya pikir itu membenarkan kita untuk mendapatkan repro dan mencari tahu apakah ini masalah umum atau tidak.

Tentu. Saat ini saya mencoba mengidentifikasi semua utas ini dan melihat statusnya masing-masing. Saya akhirnya akan menutup masalah ini dan membuka kembali masalah yang lebih spesifik yang berfokus pada setiap laporan, karena utas tunggal ini tidak berkelanjutan lagi. Saya akan menautkannya di sini untuk mereka yang ada di utas ini yang ingin mengikuti mereka.

Secara paralel saya akan mengerjakan dokumen yang mencantumkan semua rekomendasi, masalah memori yang diketahui (LOB, HttpClient, ...) dan cara menganalisis dan melaporkan masalah ini.

Hanya untuk meyakinkan Anda bahwa kami peduli dengan masalah ini dan untuk mendeteksi kebocoran memori terlebih dahulu, selama 6 bulan terakhir kami telah menjalankan aplikasi ASP.NET terus menerus di Azure, di Linux dan Windows, selama 24 jam dan 7 hari. Tes ini mengambil sumber ASP.NET terbaru pada setiap iterasi (harian atau mingguan). Kami mengukur penggunaan RPS, latensi, CPU, dan memori. Aplikasi ini menggunakan EF Core, MVC dan Razor, dan didukung hingga 50% CPU untuk mensimulasikan beban yang signifikan.

Anda dapat melihat hasilnya secara terbuka di sini di situs ini (browse untuk menemukan laporan harian): https://msit.powerbi.com/view?r=eyJrIjoiYTZjMTk3YjEtMzQ3Yi00NTI5LTg5ZDItNmUyMGRlOTkwMGRlIiwidCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsImMiOjV9&pageName=ReportSectioneeff188c61c9c6e3a798

Ini memungkinkan kami untuk memperbaiki beberapa masalah di masa lalu, dan menjadi yakin bahwa tidak ada kebocoran mendasar dalam sistem saat ini. Namun tidak ada gunanya menggunakan semua komponen yang kami kirimkan, dan mungkin ada masalah yang perlu kami identifikasi. Menyediakan dump dan aplikasi yang mereproduksi masalah adalah cara utama Anda dapat membantu kami.

@sebastienros Terima kasih atas pembaruannya. Saya tahu dalam kasus kami masalahnya lebih pada masalah "alokasi memori rakus" baru, yang awalnya kami anggap sebagai kebocoran memori. Saya bahkan tidak yakin ada masalah sekarang, mungkin saja heuristik pengoptimalan baru jauh lebih agresif. Tidak yakin ... tapi saya pikir Anda berada di jalur yang benar dengan benar-benar menilai utas ini dan menghasilkan beberapa penjelasan/ringkasan gabungan tentang apa yang orang lihat/salahpahami. Semoga beruntung!

Semua laporan individu telah diisolasi dan akan mendapatkan tindak lanjut individu, dan ditutup jika sudah diselesaikan. Jangan ragu untuk berlangganan ini agar tetap dalam lingkaran.

Secara paralel saya akan mengerjakan dokumen yang mencantumkan semua rekomendasi, masalah memori yang diketahui (LOB, HttpClient, ...) dan cara menganalisis dan melaporkan masalah ini.

Ini adalah +1 besar dari saya. Saya merasa bahwa salah satu masalah terbesar di sini adalah betapa sulitnya 'merasa' mengumpulkan informasi, untuk kemudian mencoba dan membantu menentukan _apa_ masalahnya. Memiliki beberapa dokumen hebat yang memungkinkan kami mengikuti beberapa instruksi untuk (i) mengumpulkan, (ii) mencoba mendiagnosis diri sendiri dan (iii) memposting dump/temuan kami dengan cara yang efisien untuk tim MS benar-benar dapat membantu keduanya sisi pagar.

Jika kami (pengembang) dapat lebih mampu mendiagnosis dan/atau memberikan informasi, maka ini adalah win-win untuk semua.

Sekali lagi terima kasih telah mendengarkan @sebastienros - sangat dihargai, sobat!

Apa pendapat Anda tentang situasi pada gambar di bawah ini?

Kami menjalankan 4 WebApps di dalam Paket yang sama. Awalnya adalah B1, ditingkatkan ke S2 ​​dan memori terus bertambah hingga saya menyetel ke webapp csproj yang lapar:

<ServerGarbageCollection>false</ServerGarbageCollection>

dan juga nonaktifkan Wawasan Aplikasi

  1. Saya percaya bahwa karena memori dapat dikendalikan dengan pengaturan di atas, tidak ada sisa memori. Benar?
  2. Apakah perilaku yang ditampilkan normal?

memory eaten up

Situasi yang sama di sini dengan @alexiordan , kami memiliki konsol .net core 2.1, yang menjalankan beberapa IHostedServices yang dihosting di Kube, DARI microsoft/ dotnet:2.1-runtime AS base. Kami ingin mengaktifkan HealthChecks jadi kami menambahkan asp.net hanya dengan middleware HealthChecks dan mengubah gambar dasar menjadi microsoft/ dotnet:2.1-aspnetcore-runtime. Hasilnya adalah OOM. Kami telah berhasil menstabilkan alokasi memori dengan menambahkanSalah di csproj.

Analisis kami menunjukkan bahwa dalam aplikasi asp.net GC mengumpulkan lebih jarang, juga Antrian Finalizer lebih jarang dilalui.

Juga, jika kami memaksa GC untuk mengumpulkan dan melintasi antrian finalizer dengan menambahkan yang berikut di saluran kami,

Sistem.GC.Kumpulkan();
System.GC.WaitForPendingFinalizers();
Sistem.GC.Kumpulkan();

alokasi memori tetap stabil.

Apa pendapat Anda tentang situasi pada gambar di bawah ini?

Kami menjalankan 4 WebApps di dalam Paket yang sama. Awalnya adalah B1, ditingkatkan ke S2 ​​dan memori terus bertambah hingga saya menyetel ke webapp csproj yang lapar:

<ServerGarbageCollection>false</ServerGarbageCollection>

dan juga nonaktifkan Wawasan Aplikasi

  1. Saya percaya bahwa karena memori dapat dikendalikan dengan pengaturan di atas, tidak ada sisa memori. Benar?
  2. Apakah perilaku yang ditampilkan normal?

memory eaten up

Hai @alexiordan

Kami juga melihat profil memori yang sangat mirip saat menggunakan AI (aplikasi web di net core 2.1), apakah Anda telah berkembang lebih jauh dalam memecahkan masalah ini? Jelas kami ingin menyimpan AI di aplikasi.

Aneh bahwa penggunaan tumbuh pada setiap permintaan, tetapi menyetel yang di atas ke false sepertinya menghentikannya untuk saya? aneh karena Anda akan berpikir benar akan menjadi nilai yang memungkinkannya, tetapi tampaknya sebaliknya ...

Saya lupa menyebutkan bahwa segera setelah mengumumkan niat saya untuk menulis artikel tentang masalah yang dijelaskan di utas ini, saya benar-benar melakukannya. Anda dapat melihatnya di sini: https://github.com/sebastienros/memoryleak

Muncul dengan aplikasi kecil yang membuat pola pada grafik, langsung.

tetapi menyetel yang di atas ke false sepertinya menghentikannya untuk saya? aneh karena Anda akan berpikir benar akan menjadi nilai yang memungkinkannya, tetapi tampaknya sebaliknya ...

Pengumpulan sampah klien (dioptimalkan untuk berbagi memori dengan banyak aplikasi dan menjaga memori tetap bebas) lebih agresif daripada pengumpulan sampah Server (dioptimalkan untuk throughput dan konkurensi).

Menyetel SGC ke false, api inti asp.net saya turun dari 150mb menjadi 48mb, dan tidak bertambah pada setiap permintaan setelah itu. Jadi pada kenyataannya apakah ini pengaturan terbaik untuk produksi, untuk saat ini?

@kgrosvenor sebenarnya, itu tergantung. Mengutip dari artikel @sebastienros yang luar biasa:

Pada lingkungan server web yang khas, sumber daya CPU lebih penting daripada memori, oleh karena itu menggunakan Server GC lebih cocok. Namun, beberapa skenario server mungkin lebih disesuaikan untuk Workstation GC, misalnya pada beberapa aplikasi web hosting kepadatan tinggi di mana memori menjadi sumber daya yang langka.

Terima kasih itu sangat berguna, saya akan ingat - akan mengikuti utas ini untuk pembaruan lebih lanjut, yang dikatakan saya sangat menyukai asp.net core :)

Juga menderita ini dengan aplikasi konsol .net core 2.1. pertumbuhan memori yang konstan. telah mengatur wadah buruh pelabuhan pada maksimum rendah sehingga mengenai dan memulai kembali, yang berfungsi dengan baik, tetapi jelek.

Ada berita di sisi ini? Kami juga memiliki perilaku yang sama di ASP.Net Core v2.1. Dari apa yang saya lihat di komit https://github.com/aspnet/AspNetCore/commit/659fa967a1900653f7a82f02624c7c7995a3b786 sepertinya ada masalah manajemen memori yang akan diperbaiki di v3.0?

@flo8 sudahkah Anda mencoba memutakhirkan ke 2.2 dan memeriksa perilakunya? https://dotnet.microsoft.com/download

Menjalankan 2.2 terbaru dan juga memiliki masalah ini - hanya membuat daftar 1 juta int dan mengembalikan emptyResult() akan menambah tumpukan saya beberapa ratus MB setiap permintaan hingga saya kehabisan memori. Menyetel ServerGarbageCollection ke false menyembuhkannya, meskipun sepertinya bukan perbaikan yang benar...

@dre99gsx karena sepertinya Anda mendapatkan repro yang mudah, dapatkah Anda membagikan proyek dan langkah-langkahnya sehingga saya dapat melakukan hal yang sama secara lokal?

Dalam hal ini harus mengisi LOB tetapi mereka harus dikumpulkan pada gen2. Juga tolong bagikan lingkungan apa yang dapat saya repro ini, OS, memori, muat.

Maaf atas tanggapan yang samar. Cukup mudah:
(Windows 7 64bit, ram 16GB, Google chrome untuk permintaan http, komunitas VS2017) - Saya masih terbiasa menambahkan kode ke utas ini, maafkan penampilannya)

  • mulai Aplikasi Web .NET Core 2.2 baru
  • Suntikkan kelas layanan, tercakup (tidak ada yang istimewa..) ke dalam konstruktor pengontrol
  • Minta tindakan Index() dari pengontrol memanggil metode kelas layanan ini
  • Buat kelas model (DumbClass) dengan satu properti: public int ID {get; mengatur;}
  • Dalam metode kelas layanan, buat instance daftar dan isi:
    var lst = Daftar baru();
    for (i=0; i<10000000; i++) <--- catatan: 10 juta iterasi
    {
    lst.add(Kelas Bodoh baru(){ID=i});
    }
  • kembali dari metode, tidak perlu mengembalikan apa pun, tetapi Anda juga dapat mengembalikan daftar itu ...
  • index() mengembalikan EmptyResult() baru;

Sekarang panggil saja aksinya setiap 8 detik, dan saksikan memori profiler naik. Di sistem saya, inilah yang saya lihat di Private Bytes:

Mulai aplikasi: 155MB
http pertama mendapatkan permintaan: 809MB
ke-2: 1.2GB
Ketiga: 1.4GB
4: 1,8 GB
5: 2.1GB ... 2.3GB.. 2.6GB...

Sekarang, di beberapa titik, GC tampaknya mulai, tetapi tidak pernah turun di bawah 3GB dalam contoh ini. Seperti yang disebutkan, jika saya mengubah ServerGC menjadi false, tidak pernah naik di atas 1GB, meskipun masih naik di sana dan melayang di 1GB.

Beri tahu saya jika itu membantu, dan jika Anda dapat mereproduksinya. Oh, saya membaca posting github Anda: "Manajemen dan Pola Memori di ASP.NET Core", tulisan yang fantastis, terima kasih telah berkontribusi!

@ dre99gsx

Saya masih terbiasa menambahkan kode ke utas ini, maafkan penampilannya)

Tidak ada masalah sama sekali :) Pertanyaan: bisakah Anda benar-benar menempatkan seluruh contoh aplikasi ke GitHub (repo gratis) atau di tempat yang serupa? Itulah cara paling sederhana bagi siapa pun untuk dengan cepat mengkloning/mengunduh _seluruh_ aplikasi sampel/repo yang tepat, yang telah Anda mainkan.

Juga, tangkapan layar penggunaan memori menggunakan TaskManager akan membantu (jika di windows - atau yang setara dengan *nix .. yang merupakan perintah top ??)

Upaya besar sejauh ini!

/me kembali diam-diam menonton utas ini dengan sungguh-sungguh.

Pengingat Anda dapat melihat beberapa demo dan penjelasan untuk semua gejala yang dijelaskan di utas di sini: https://github.com/sebastienros/memoryleak

Juga masing-masing masalah ini telah ditangani secara individual dan tidak ada yang terbukti sebagai bug di inti dotnet __sejauh ini__, tetapi perilaku yang diharapkan.

@dre99gsx Sekarang kembali ke komentar terbaru, saya akan mendorong Anda untuk mengajukan masalah terpisah dari utas ini. Berada di ponsel saya, saya tidak menyadari itu adalah "yang ini" ;). Dari komentar pertama Anda, Anda menyatakan

sampai aku kehabisan memori

Jadi saya mengharapkan pengecualian OutOfMemory, itulah sebabnya saya meminta repro. Tetapi dalam komentar Anda berikutnya, Anda menyatakan:

Sekarang, di beberapa titik, GC tampaknya masuk, tetapi tidak pernah turun di bawah 3GB dalam contoh ini

Jadi tidak ada masalah memori. Ini khas dari mesin dengan banyak inti dan banyak memori yang tersedia. GC akan mengosongkan tumpukan terkelola, tetapi memori akan tetap dikomit karena tidak ada alasan untuk membatalkan komit (banyak memori yang tersedia). Ini adalah perilaku standar di .NET, dan saya demo di artikel yang saya tunjukkan. Anda juga dapat membaca ini: https://blogs.msdn.microsoft.com/maoni/2018/11/16/running-with-server-gc-in-a-small-container-scenario-part-0/

Saya tahu bahwa tim runtime saat ini sedang mengerjakan cara untuk membatasi aplikasi .NET yang berjalan dalam wadah sehingga tidak menggunakan banyak memori, menargetkan 3.0, untuk menyelesaikan beberapa skenario layanan mikro.

Dan seperti yang Anda temukan sendiri, jika aplikasi Anda tidak dapat menggunakan semua memori yang tersedia di server, Anda harus menggunakan mode GC workstation.

Benar, ketika saya menyatakan "kehabisan memori", saya mendasarkan bahwa secara visual tidak melihat memori yang tersedia untuk aplikasi lain melalui Windows Private Working Set (Task Manager); bukan "Pengecualian Memori Habis".

Anda tahu apa, Anda benar. Ini semakin terlihat seperti perilaku yang diharapkan, dan jika ada begitu banyak memori yang tersedia, mengapa menghabiskan sumber daya untuk membebaskannya jika tidak ada orang lain yang membutuhkannya! Saya mengerti. Selama GC cukup pintar untuk mengosongkan memori sehingga aplikasi lain tidak terbatas , saya akan membiarkannya apa adanya dan membiarkannya melakukan tugasnya. Terima kasih lagi!

Saya telah mengembangkan aplikasi saya di Asp.net core 2.2 juga menghadapi masalah yang sama terkait dengan pelepasan memori.
setiap panggilan meningkatkan memori dalam kisaran 40-50 Mb setiap kali tidak pernah mendapatkan rilis.

Saya juga telah menambahkan tag yang disebutkan ServerGarbageCollection>false
masih menghadapi masalah yang sama untuk 50 pengguna yang menggunakan kira-kira 2GB RAM dalam mode Dalam Proses (proses pekerja w3wp iis)

Tolong bantu.

Tolong bantu !! masalah yang sama dengan ankitmori14

@ankitmori14 , @ikourfaln - jika Anda telah membaca komentar @sebastienros di https://github.com/aspnet/AspNetCore/issues/1976#issuecomment -449675298 dan masih yakin ada masalah memori, harap ajukan masalah baru dengan langkah-langkah terperinci untuk mereproduksi masalah, ditambah informasi dan jejak lain yang Anda miliki tentang perilaku tersebut. Harap diingat bahwa kecuali aplikasi/proses benar- benar mengalami kesalahan, kecil kemungkinan (tetapi bukan tidak mungkin) ada bug. Pengumpul Sampah 'Server' default tidak mencoba menggunakan memori sesedikit mungkin; itu agak menendang ketika perlu , seperti ketika memori benar-benar habis. Jadi aplikasi kecil pun mungkin menggunakan memori 2GB dan itu tidak masalah karena masih ada 4GB yang gratis.

Hai,

Kami mengalami masalah ini: https://stackoverflow.com/questions/53868561/dotnet-core-2-1-hoarding-memory-in-linux

Pada dasarnya memori bertambah selama berhari-hari dalam proses sampai Kubernetes membunuhnya karena mencapai batas yang dikonfigurasi 512Mb. Lucunya, memori turun drastis saat mengambil dump memori, tanpa proses restart atau apa pun. Memeriksa dump memori, kami melihat banyak objek tanpa root.

Kami juga menonaktifkan GC bersamaan (yaitu: GC latar belakang) kemarin dan tampaknya lebih baik sekarang, tetapi kami harus menunggu setidaknya seminggu untuk mengonfirmasi.

<PropertyGroup>
  <ServerGarbageCollection>false</ServerGarbageCollection>
  <ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>
</PropertyGroup>

@vtortola pertanyaan, ketika Anda mengonfigurasi batas 512Mb untuk aplikasi Anda, apakah Anda memiliki gagasan tentang jumlah permintaan bersamaan yang ingin Anda tangani atau uji berapa banyak permintaan bersamaan yang dapat ditangani aplikasi Anda sebelum gagal??

Kami melakukan beberapa pengujian pendahuluan dan kasar dan memeriksa bahwa kami dapat menangani 500 soket web bersamaan per pod menggunakan 512Mb. Kami berlari selama berjam-jam dengan 2 pod dan 1000 koneksi bersamaan dengan memori kurang dari 150Mb . Aplikasi yang disebarkan, dengan 2 pod, memiliki antara 150 dan 300 koneksi bersamaan setiap saat, dan memori bervariasi dari kurang dari 100Mb pada beberapa hari pertama, hingga mencapai 512Mb dalam waktu sekitar 2 minggu. Tampaknya tidak ada korelasi antara jumlah koneksi dan memori yang digunakan. Lebih dari 70% koneksi bertahan 10 menit.

Bisakah Anda membagikan dump memori saat berukuran 100MB dan 512MB untuk melihat instance apa yang masih hidup?

Saya khawatir saya tidak dapat membagikan dump, karena berisi cookie, token, dan banyak data pribadi.

Bisakah Anda membandingkannya secara lokal? Dalam hal objek apa yang mengambil memori paling banyak, dan jika jumlahnya tidak berkorelasi dengan beban Anda. Seperti jika Anda memiliki 300 koneksi, seharusnya tidak ada objek koneksi 3K.

Sayangnya pengujian pengaturan <ConcurrentGarbageCollection>false</ConcurrentGarbageCollection> tidak membantu dan prosesnya masih menimbun memori.

Kami memiliki proses dump linux, satu-satunya alat yang kami miliki untuk menganalisisnya adalah lldb dan kami sangat noob dalam hal ini.

Berikut beberapa data jika membunyikan lonceng:

(lldb) eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x00007F8481C8D0B0
generation 1 starts at 0x00007F8481C7E820
generation 2 starts at 0x00007F852A1D7000
ephemeral segment allocation context: none
         segment             begin         allocated              size
00007F852A1D6000  00007F852A1D7000  00007F853A1D5E90  0xfffee90(268430992)
00007F84807D0000  00007F84807D1000  00007F8482278000  0x1aa7000(27947008)
Large object heap starts at 0x00007F853A1D7000
         segment             begin         allocated              size
00007F853A1D6000  00007F853A1D7000  00007F853A7C60F8  0x5ef0f8(6222072)
Total Size:              Size: 0x12094f88 (302600072) bytes.
------------------------------
GC Heap Size:            Size: 0x12094f88 (302600072) bytes.

Dan hasil dari dumpheap -stat : https://Pastebin.com/ERN7LZ0n

Anda dapat menemukan bagaimana Grafana melaporkan status memori di https://stackoverflow.com/questions/53868561/dotnet-core-2-1-hoarding-memory-in-linux

Kami memiliki banyak layanan lain di inti dotnet yang bekerja dengan sempurna, meskipun mereka tidak menggunakan soket web.

@vtortola maukah Anda membuat masalah baru sehingga kami tidak memotong yang ini. Saya pikir fakta menggunakan WebSockets membuatnya unik dan kami perlu membuat setidaknya aplikasi sampel yang akan berperilaku seperti milik Anda dan menekankannya dalam jangka waktu yang lama. Bisakah Anda menjelaskan apa yang klien Anda lakukan dengan websocket, bagaimana mereka terhubung, dan untuk berapa lama? Saya dapat menyiapkan aplikasi seperti ini dan menjalankannya selama berhari-hari, dan membuang memori jika saya melihat memori bertambah.

Mungkin juga ada konflik antara GC dan Kubernetes, sehingga GC tidak diperingatkan bahwa itu mendekati batas pod.

@richlander sedang mengerjakan masalah serupa. Kaya, apakah kasus ini (baca 6 komentar terakhir saja) dapat dikaitkan dengan apa yang sedang Anda kerjakan?

jika ada bedanya, saya memiliki masalah yang sama (atau sangat mirip). Saya memiliki selusin+ aplikasi konsol .net core 2.1 dan 2.2 yang berjalan di buruh pelabuhan - setiap wadah dengan batas memori 512mb, juga menggunakan soket web (klien), dan aplikasi mencapai batas memori wadah setiap ~3 hari. Kontainer kemudian mati dan restart.

Semuanya menggunakan layanan yang diautentikasi, jadi saya tidak dapat memberikan apa yang saya miliki, tetapi saya mungkin dapat menggabungkan sesuatu yang menggunakan situs pengujian untuk mereproduksi masalah tersebut.

Parameter apa yang Anda gunakan untuk mengatur batas memori? Hanya --memory atau juga --memory-swap ?

Ketika saya mengujinya, saya dapat melihatnya diperhitungkan dengan sangat baik, tidak pernah melampaui batas yang saya tetapkan, bahkan dengan batas yang sangat rendah seperti 16MiB, namun ia bertukar pada disk seperti orang gila. Dan saya menguji dengan aplikasi yang melakukan rendering db query (EF) dan Razor views.

@sebastienros benar-benar, saya membuat https://github.com/aspnet/AspNetCore/issues/6803

Beri tahu saya jika Anda membutuhkan informasi lebih lanjut.

Saat ini saya mengalami masalah memori.

Setelah satu jam dalam produksi, semua memori digunakan oleh proses w3wp.exe (menjalankan .NET Core InProcess). Mengubah GC ke Workstation, tidak berhasil bagi saya.

Setelah menganalisis dump memori, saya menemukan masalah serupa ini, https://github.com/aspnet/AspNetCore/issues/6102 .

Saya berharap untuk mengujinya dalam produksi hari ini, setelah memutakhirkan ke .NET Core run time terbaru, saat ini 2.2.3. Saya akan memberi tahu Anda bagaimana kelanjutannya.

Saya mengalami masalah serupa dengan penggunaan memori. Jika saya menetapkan batas pada wadah Linux saya, itu hanya membuat OOM lebih cepat. Itu bahkan terjadi dengan menggunakan template dasar di Visual Studio. Satu hal yang saya temukan - Core 2.1 dan 2.2 terpengaruh. Core 2.0 tidak - tapi itu EOL :(

Lihat di atas

Saya tahu bahwa tim runtime saat ini sedang mengerjakan cara untuk membatasi aplikasi .NET yang berjalan dalam wadah sehingga tidak menggunakan banyak memori, menargetkan 3.0, untuk menyelesaikan beberapa skenario layanan mikro.

Dan seperti yang Anda temukan sendiri, jika aplikasi Anda tidak dapat menggunakan semua memori yang tersedia di server, Anda harus menggunakan mode GC workstation.

Sayangnya mode workstation tidak membantu sama sekali - sayangnya saya tidak benar-benar dalam posisi untuk mencoba salah satu pratinjau 3.0 atau yang serupa.

@PrefabPanda pastikan Anda benar-benar berjalan dalam mode GC workstation dengan memeriksa bahwa System.Runtime.GCSettings.IsServerGC adalah false .

Maka ini bisa jadi kebocoran memori asli. Buka masalah terpisah mungkin langkah terbaik.

@wanton7 - terima kasih, saya sudah memeriksa ulang dan itu sudah pasti.

@DAllanCarr - akan melakukannya

Saya hampir yakin itu bukan kebocoran memori. Lebih seperti pengaturan Docker mungkin tidak ditegakkan dengan benar dan GC tidak masuk sebelum batas tercapai. Saya tahu bahwa 3.0 memperkenalkan perbaikan dalam pengertian ini.

@richlander apakah masalah ini terlihat seperti sesuatu yang diketahui tidak berfungsi di 2.2?

@PrefabPanda maukah Anda membagikan versi buruh pelabuhan yang tepat yang Anda gunakan dan file pembuatan buruh pelabuhan? Saya mencoba melakukan repro tetapi antara versi docker dan docker-compose saya kesulitan mereplikasi masalah ini secara lokal.

@sebastienros , @richlander - Terima kasih telah menghubungi saya kembali. Saya sangat menghargainya.

Versi Docker saya:

Komunitas Desktop Docker
Versi 2.0.0.2 (30215)

Mesin: 18.09.1
Tulis: 1.23.2

Lihat terlampir seluruh proyek pengujian:
Aplikasi Web1.zip

uji curl request.zip

Untuk jaga-jaga, Dockerfile saya:

DARI mcr.microsoft.com/dotnet/core/ aspnet:2.2 AS base
WORKDIR / aplikasi
paparan 80
Paparan 443

DARI mcr.microsoft.com/dotnet/core/ sdk:2.2 AS build
WORKDIR /src
SALIN ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
JALANKAN dotnet restore "WebApplication1/WebApplication1.csproj"
SALIN. .
WORKDIR "/src/WebApplication1"
JALANKAN dotnet build "WebApplication1.csproj" -c Rilis -o /app

DARI build SEBAGAI publikasikan
JALANKAN dotnet publish "WebApplication1.csproj" -c Rilis -o /app

DARI dasar AS final
WORKDIR / aplikasi
SALIN --from=publish /app .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]

docker-compose.yml:

versi: '2.4'

jasa:
aplikasi web1:
gambar: ${DOCKER_REGISTRY-}aplikasi web1
mem_reservasi: 128m
mem_limit: 256m
memswap_limit: 256m
CPU: 1
membangun:
konteks: .
dockerfile: WebApplication1/Dockerfile

docker-compose-override.yml:

versi: '2.4'

jasa:
aplikasi web1:
lingkungan:
- ASPNETCORE_ENVIRONMENT=Pengembangan
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_HTTPS_PORT=44329
- DOTNET_RUNNING_IN_CONTAINER=benar
- DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=benar
- ASPNETCORE_preventHostingStartup=true
port:
- "50996:80"
- "44329:443"
volume:
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/ https:ro
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/us ersecrets:ro

@sebastienros - bahkan jika ada cara saya dapat menempatkan variabel lingkungan terpisah ke dalam wadah untuk dilihat GC, itu akan berfungsi dengan baik untuk saya.

Saya telah mencoba memanggilnya secara eksplisit, tetapi tidak membantu - saya berasumsi bahkan ketika memanggilnya dalam kode masih melihat ukuran memori yang salah dari wadah/mesin.

@PrefabPanda ketika Anda mengatakan "Saya telah mencoba memanggilnya secara eksplisit", dapatkah Anda menjelaskan apa artinya sebenarnya? GC melihat batas memori wadah yang benar jika Anda memilikinya, apakah itu dipicu secara alami atau diinduksi. jika Anda memanggil GC.Collect(), itu akan melakukan koleksi pemblokiran penuh; dan jika Anda melakukan GC.Collect(2, GCCollectionMode.Default, true, true) itu akan melakukan GC pemadatan penuh, ketika ini mengembalikan heap pada ukuran sekecil mungkin, terlepas dari batas wadah atau apa pun.

Hai @Maoni0 - Saya sudah mencoba GC.Collect(2, GCCollectionMode.Default, true, true)

Saya baru saja melihat komentar lain yang mengatakan 256MB terlalu kecil untuk 2.2, tetapi mungkin 'diperbaiki' di 3.0. Sepertinya saya harus bereksperimen lagi...

jika Anda sudah mencoba GC.Collect(2, GCCollectionMode.Default, true, true) dan memori tidak turun seperti yang Anda harapkan, itu berarti Anda mengalami kebocoran memori yang sebenarnya. tidak yakin berapa banyak perkakas yang tersedia di lingkungan Anda. dapatkah Anda menjalankan perintah sos sama sekali? jika demikian, Anda selalu dapat melihat untuk melihat apa yang tersisa di heap setelah GC yang Anda induksi

Terima kasih @ Maoni0 - ingatlah bahwa saya menggunakan templat di Visual studio - secara harfiah tidak ada kode saya sendiri dalam proyek pengujian yang saya lampirkan ini. Saya punya beberapa umpan balik lain untuk dikerjakan, saya akan menghubungi Anda. Terimakasih banyak.

@Maoni0 - Saya mencoba mengatur batas yang lebih tinggi, tidak ada perbedaan. Sepertinya saya harus mencoba pratinjau 3.0

Saya ingin mengunci komentar tentang masalah ini karena ini adalah komentar yang sangat lama yang membuat semua kasusnya ditangani dalam masalah terpisah. Saya mengomentari yang ini karena kesalahan berpikir saya mengomentari https://github.com/aspnet/AspNetCore/issues/10200

Terima kasih

Apakah halaman ini membantu?
0 / 5 - 0 peringkat