pembangunan bahagian belakang
Tutorial C#.Net
Bagaimana untuk mengoptimumkan penggunaan memori dalam aplikasi C#?
Bagaimana untuk mengoptimumkan penggunaan memori dalam aplikasi C#?
Utamakan menggunakan Span
dan Memory dan bukannya tatasusunan untuk mengurangkan peruntukan timbunan dan tekanan GC; Span sesuai untuk penghirisan kitaran hayat pendek dalam kaedah, dan Memory digunakan untuk menyeberangi sempadan tak segerak; elakkan operasi overhed tinggi seperti ToArray(), tinju dan penyambungan rentetan; buang sumber IDisposable tepat pada masanya dan gunakan semula objek berat seperti HttpClient.

Gunakan Span<t></t> dan Memory<t></t> bukannya tatasusunan untuk kepingan mesra tindanan
Tatasusunan sementara yang besar mencetuskan peruntukan timbunan dan tekanan GC. Span<t></t> membolehkan anda memotong memori sedia ada (cth, tatasusunan, blok stackalloc) tanpa menyalin atau memperuntukkan — selagi hayat dihadkan kepada skop kaedah semasa.
Kesilapan biasa: menghantar Span<t></t> kepada kaedah async atau menyimpannya dalam medan — itu tidak sah dan menyebabkan ralat penyusunan atau kegagalan masa jalan. Gunakan Memory<t></t> hanya apabila anda perlu melepasi sempadan tak segerak atau menahan rujukan lebih lama, tetapi ketahui ia mungkin memperuntukkan pembalut MemoryManager<t></t> di bawah hud.
- Lebih suka
stackalloc byte[1024]Span<byte></byte>untuk penimbal jangka pendek (cth, menghuraikan pengepala) - Elakkan
ToArray()padaSpan<t></t>melainkan anda benar-benar memerlukan tatasusunan terurus - Apabila interoping dengan kod asli, gunakan
Span<t></t>terus — tiada overhed marshalling
Elakkan tinju dan peruntukan tali yang tidak perlu
Nilai jenis tinju (cth, int → object ) mencipta objek timbunan. Penggabungan rentetan dengan dalam gelung membina banyak rentetan perantaraan. Kedua-duanya muncul dengan jelas dalam pemprofil memori sebagai "churn".
Gunakan StringBuilder untuk membina rentetan berbilang langkah dan lebih suka string.Create() untuk pembinaan seperti format tanpa overhed interpolasi. Untuk pengelogan atau diagnostik, tangguhkan pemformatan sehingga diperlukan menggunakan string.Format(IFormatProvider, ...) atau perpustakaan pengelogan berstruktur yang menerima ReadOnlySpan<char></char> .
- Gantikan
list.Add(i.ToString())denganlist.Add(i.ToString(CultureInfo.InvariantCulture))— mengelakkan peruntukan sensitif budaya - Lebih suka
ReadOnlySpan<char>.Contains()</char>daripadastring.Contains()apabila sumber sudah menjadiSpanatauReadOnlySpan - Jangan panggil
ToString()pada enum dalam laluan panas — gunakanEnum.GetName(typeof(T), value)sekali sahaja, cache jika diulang
Lupuskan sumber IDisposable dengan segera — terutamanya yang besar
Tidak melupuskan objek seperti Bitmap , FileStream atau HttpClientHandler bukan sahaja membocorkan memori yang tidak terurus — ia juga menangguhkan pemuktamadn, yang memastikan objek terurus yang berkaitan (cth, penimbal, pemegang) hidup lebih lama daripada yang diperlukan.
HttpClient ialah perangkap klasik: mencipta satu setiap permintaan memperuntukkan objek HttpConnectionPool dalaman dan kejadian ArrayPool<byte></byte> . Gunakan semula satu contoh (atau gunakan IHttpClientFactory dalam ASP.NET Core).
- Gunakan
usingpernyataan atauusingpengisytiharan — jangantry/finallymelainkan anda memerlukan pelupusan bersyarat - Semak perpustakaan pihak ketiga: sesetengahnya mendedahkan kaedah
Free(),Reset()atauClear()yang melepaskan penimbal dalaman (cth,JsonSerializerOptionstidak, tetapiUtf8JsonWritermelakukannya melalui pelupusan aliran asasFlush()) - Berhati-hati dengan
async using: ia menantiDisposeAsync(), tetapi banyak jenis masih memegang memori sehingga operasi async selesai — profil sebelum menganggap ia "lebih ringan"
Profil sebelum mengoptimumkan — fokus pada saiz yang dikekalkan, bukan hanya bait yang diperuntukkan
Memperuntukkan 100 KB/s kelihatan buruk sehingga anda melihat objek hidup
Gunakan dotMemory atau Alat Diagnostik Visual Studio untuk menangkap syot kilat, kemudian mengisih mengikut "Saiz Tertahan". Cari punca yang tidak dijangka: kamus statik yang memegang MethodInfo , kejadian Regex cache dengan bendera Compiled atau penyalahgunaan WeakReference (cth, terlupa untuk menyemak IsAlive sebelum mengakses Target ).
- Dayakan pengesanan koleksi GC (
DOTNET_GC_LOG=1) untuk mengaitkan jeda dengan lonjakan peruntukan - Tetapkan
GC.Collect(2, GCCollectionMode.Forced, blocking: true)hanya dalam ujian — tidak sekali-kali dalam logik pengeluaran - Ingat:
ArrayPool<byte>.Shared.Rent(8192)</byte>mengurangkan peruntukan, tetapi tatasusunan yang disewa tidak disifarkan — sentiasa kosongkan data sensitif sebelum kembali
Kemenangan memori terbesar biasanya datang daripada perubahan jangka hayat data — bukan pengoptimuman mikro talian individu. Jika objek hidup lebih lama daripada skop logiknya, tiada jumlah Span atau pengumpulan akan membantu.
Atas ialah kandungan terperinci Bagaimana untuk mengoptimumkan penggunaan memori dalam aplikasi C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!
Alat AI Hot
Undress AI Tool
Gambar buka pakaian secara percuma
AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.
Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik
Stock Market GPT
Penyelidikan pelaburan dikuasakan AI untuk keputusan yang lebih bijak
Artikel Panas
Alat popular
Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma
SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan
Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa
Dreamweaver CS6
Alat pembangunan web visual
SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)
Topik panas
Bagaimana untuk mengesahkan alamat e-mel dalam C#? (Corak regex)
Mar 08, 2026 am 12:06 AM
Adalah disyorkan untuk menggunakan biasa rasmi ringan Microsoft ^[a-zA-Z0-9._% -] @[a-zA-Z0-9.-] \.[a-zA-Z]{2,}$ untuk pengesahan format e-mel asas, meliputi 99% daripada input sebenar; cara yang lebih dipercayai ialah menggunakan pembina MailAddress dan hanya menangkap FormatException, sambil mengesahkan rentetan null/kosong terlebih dahulu.
Bagaimana untuk menggunakan refleksi untuk mendapatkan nilai harta dalam C#? (GetType)
Mar 06, 2026 am 12:15 AM
GetProperty harus digunakan bersama dengan GetValue untuk mendapatkan nilai harta dan bukannya hanya memanggil GetType; adalah perlu untuk memberi perhatian kepada butiran seperti keterlihatan harta, perhubungan warisan dan pengindeks, dan disyorkan untuk cache PropertyInfo untuk meningkatkan prestasi.
Bagaimana untuk menggunakan sifat dengan get set dalam C#? (Encapsulation)
Mar 10, 2026 am 12:33 AM
get/set tidak hanya menambah kurungan, tetapi merangkum titik permulaan: medan eksplisit diperlukan, operasi yang memakan masa dielakkan, ArgumentException dilemparkan apabila pengesahan gagal, pengubah suai akses berbeza disokong, init terhad kepada senario permulaan dan atribut logik pada asasnya ialah kaedah. Perhatian khusus mesti diberikan kepada penyahpepijatan dan prestasi.
Bagaimana untuk memisahkan rentetan dengan pembatas dalam C#? (String.Split)
Mar 12, 2026 am 12:21 AM
Ya, String.Split mengembalikan rentetan kosong secara lalai, menyebabkan item kosong disebabkan oleh pembatas berterusan atau pertama dan terakhir; anda perlu menggunakan StringSplitOptions.RemoveEmptyEntries untuk menapis, atau menapis secara manual; char[] digunakan untuk pemisahan aksara tunggal, dan rentetan[] digunakan untuk pemisahan subrentetan; Span.Split boleh mengelakkan peruntukan; melepasi had atas nombor akan memotong keputusan.
Bagaimana untuk menggunakan jenis nullable dalam C#? (Jenis rujukan boleh batal)
Mar 06, 2026 am 12:14 AM
Selepas mendayakan nullable, rentetan bermaksud bukan nol (ralat akan dilaporkan jika null diberikan atau dereference tidak dikesan), string? secara eksplisit membenarkan null; fail lama perlu #nullableenable secara eksplisit untuk berkuat kuasa; API luaran lalai kepada kemungkinan null.
Bagaimana untuk menyertai rentetan dengan pemisah dalam C#? (String.Join)
Mar 13, 2026 am 12:02 AM
String.Join direka khas untuk penyambungan rentetan. Ia selamat, cekap dan sangat mudah dibaca. Hanya masukkan pembatas dan tatasusunan rentetan, dan elemen nol akan dilangkau secara automatik. Tatasusunan kosong atau null akan mengembalikan rentetan kosong. Pemformatan eksplisit diperlukan untuk mengendalikan jenis bukan rentetan. Dalam senario sensitif prestasi, tatasusunan diluluskan dahulu dan bukannya IEnumerable. StringBuilder sesuai untuk logik yang kompleks.
Bagaimana untuk menulis ke fail teks dalam C#? (Contoh StreamWriter)
Mar 05, 2026 am 12:14 AM
Anda mesti menggunakan menggunakan untuk memastikan bahawa StreamWriter dikeluarkan dengan betul. Laluan perlu dibina dengan Path.Combine dan direktori mesti dibuat terlebih dahulu. File.WriteAllText atau File.AppendAllText lebih disukai untuk memudahkan operasi.
Bagaimana untuk mengukur masa pelaksanaan dalam C#? (Kelas jam randik)
Mar 16, 2026 am 12:13 AM
Jam randik.Start() perlu dipanggil untuk kejadian yang tidak dimulakan, jika tidak InvalidOperationException akan dilemparkan; StartNew() ialah kaedah statik yang boleh dibuat dan dimulakan dalam satu langkah, menjadikannya lebih selamat dan lebih biasa digunakan.





