C#學習26天:內存優化的幾種方法

1.減少對象創建


使用場景:

  • 在循環或密集計算中頻繁創建對象時。
  • 涉及大量短生命周期對象的場景,比如日志記錄或字符串拼接。
  • 游戲開發中,需要頻繁更新對象狀態時。?

說明:

  • 重用對象可以降低內存分配和垃圾回收的開銷。
  • 使用對象池(Object Pooling)技術來管理可重用對象的生命周期

?示例:

// 不優化的情況:每次都創建新的 StringBuilder
for (int i = 0; i < 1000; i++)
{var builder = new StringBuilder();builder.Append("Number: ");builder.Append(i);Console.WriteLine(builder.ToString());
}// 優化后的情況:重用同一個 StringBuilder
var sharedBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{sharedBuilder.Clear();sharedBuilder.Append("Number: ");sharedBuilder.Append(i);Console.WriteLine(sharedBuilder.ToString());
}

2.使用合適的數據結構


使用場景:

  • 數據量固定且不需要動態增刪時,使用數組代替列表。
  • 需要快速查找、添加和刪除操作時,選擇字典(Dictionary)或哈希表(HashSet)。
  • 在多線程環境中使用并發集合(如 ConcurrentDictionary)以保證線程安全。?

說明:

  • 選擇合適的數據結構可以提高程序的性能和內存利用率。
  • 在使用大型數據集合時,數據結構的選擇尤為關鍵。

示例:?

// 使用 List<T>
List<int> numbersList = new List<int> { 1, 2, 3, 4, 5 };// 使用 Array
int[] numbersArray = new int[] { 1, 2, 3, 4, 5 };// 當數據量固定時,Array 比 List<T> 更節省內存Dictionary<int, string> employeeDirectory = new Dictionary<int, string>();employeeDirectory[1002] = "Robert";//快速查找更新,字典更快捷

3.使用 struct 代替 class(在合適的場景)


使用場景:

  • 小型數據結構,如幾何坐標(Point)、顏色(Color)等。
  • 不需要繼承或復雜對象行為的簡單數據容器。
  • 大量創建和銷毀對象的場景,如物理引擎中的向量計算。

說明:

  • struct 提供值語義,存儲在棧上,減少了堆內存的使用。
  • 需要注意避免 struct 過大,因為大結構體會增加復制的成本。

示例:

// 使用 class
class PointClass
{public int X { get; set; }public int Y { get; set; }
}
// 使用 struct
struct PointStruct
{public int X { get; set; }public int Y { get; set; }
}// struct 通常會節省內存,尤其是在大量小對象的情況下
// 使用 class
void ProcessPointsClass()
{for (int i = 0; i < 1000000; i++){PointClass p1 = new PointClass(i, i);}
}
// 使用 struct
void ProcessPointsStruct()
{for (int i = 0; i < 1000000; i++){PointStruct p1 = new PointStruct(i, i);}
}

4.避免裝箱和拆箱


使用場景:

  • 在高性能要求的代碼中,尤其是涉及到泛型集合的頻繁操作。
  • 需要使用非泛型集合或接口時,盡量避免將值類型裝箱。
  • 數據密集型應用,如數據處理、實時計算等。

說明:

  • 使用泛型集合(如 List<int> 而非 ArrayList)可以避免裝箱。
  • 頻繁裝箱和拆箱不僅浪費內存,還會影響性能。

示例:

using System;
using System.Collections;
class Program
{static void Main(){ArrayList list = new ArrayList();// 裝箱:整數被包裝成對象list.Add(42);// 拆箱:對象被轉換回整數int value = (int)list[0];Console.WriteLine($"Value: {value}");}
}using System;
using System.Collections.Generic;
class Program
{static void Main(){List<int> list = new List<int>();// 不需要裝箱:整數直接存儲為值類型list.Add(42);// 不需要拆箱:整數直接檢索為值類型int value = list[0];Console.WriteLine($"Value: {value}");}
}

5.使用 StringBuilder 替代字符串連接


使用場景:

  • 在循環中進行字符串拼接操作。
  • 構造長文本或動態生成 HTML/CSS/SQL 查詢等。
  • 需要頻繁修改字符串的場景,如日志記錄系統。

說明:

  • StringBuilder 是為高效字符串操作而設計的,避免了不必要的中間對象。
  • 尤其適用于構建長字符串或需要多次修改字符串的場景

示例:

// 不使用 StringBuilder
string result = "";
for (int i = 0; i < 100; i++)
{result += i.ToString(); // 創建多個中間字符串對象
}// 使用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{sb.Append(i.ToString());
}
string optimizedResult = sb.ToString(); // 更高效

6.使用 using 語句管理資源


使用場景:

  • 需要使用 IDisposable 接口的對象,如文件流、數據庫連接、網絡資源等。
  • 網絡通信、文件讀寫、數據庫操作等需要保證資源正確釋放的場景。
  • 任何需要顯式釋放資源以避免內存泄漏的情況。

說明:

  • using 語句確保對象在使用完后立即釋放資源,減少內存壓力。
  • 限定資源的生存周期,避免資源長時間占用。

示例:

using System;
using System.IO;class Program
{static void Main(){string filePath = "example.txt";// 使用 using 語句確保文件在讀取后正確關閉using (StreamReader reader = new StreamReader(filePath)){string line;while ((line = reader.ReadLine()) != null){Console.WriteLine(line);}} // 離開 using 塊時,reader 對象的 Dispose 方法被自動調用Console.WriteLine("文件讀取完畢,資源已釋放。");}
}

7.合理使用弱引用 WeakReference?


使用場景:

  • 需要緩存數據但又不希望緩存對象長期占用內存時。
  • 實現某種形式的對象緩存,如圖像緩存、數據庫查詢結果緩存等。
  • 需要在內存不足時允許垃圾回收的非關鍵對象。

說明:

  • 弱引用允許垃圾回收器回收未使用的對象,避免內存溢出。
  • 適合偶爾使用但不希望長期占用內存的對象。

示例:

using System;
using System.Collections.Generic;
using System.Drawing;class Program
{// 使用字典來存儲圖像的弱引用緩存static Dictionary<string, WeakReference> imageCache = new Dictionary<string, WeakReference>();static void Main(){string imagePath = "example.png";Bitmap image = LoadImage(imagePath);if (image != null){Console.WriteLine("圖像已加載并緩存。");}else{Console.WriteLine("圖像加載失敗。");}// 強制垃圾回收以演示弱引用效果GC.Collect();GC.WaitForPendingFinalizers();// 再次嘗試從緩存加載圖像image = LoadImage(imagePath);if (image != null){Console.WriteLine("圖像已從緩存中重新加載。");}else{Console.WriteLine("圖像已被垃圾回收器回收。");}}static Bitmap LoadImage(string path){if (imageCache.TryGetValue(path, out WeakReference weakRef) && weakRef.IsAlive){Console.WriteLine("從緩存中獲取圖像...");return weakRef.Target as Bitmap;}else{Console.WriteLine("加載新圖像...");Bitmap img = new Bitmap(path);// 將圖像加載到緩存中imageCache[path] = new WeakReference(img);return img;}}
}

這些優化策略在合適的場景中可以顯著提高內存使用效率,并提高應用程序的整體性能。根據具體的應用需求,選擇適當的方法進行優化是關鍵。希望這些場景描述能幫助你更好地理解和應用這些內存優化策略!如果需要進一步的幫助,請隨時提問。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83796.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【opencv】基礎知識到進階(更新中)

安裝&#xff1a;pip install opencv-python 入門案例 讀取圖片 本節我們將來學習,如何使用opencv顯示一張圖片出來,我們首先需要掌握一條圖片讀取的api cv.imread("圖片路徑","讀取的方式") # 圖片路徑: 需要在工程目錄中,或者一個文件的絕對路徑 # 讀取…

【Part 3 Unity VR眼鏡端播放器開發與優化】第二節|VR眼鏡端的開發適配與交互設計

文章目錄 《VR 360全景視頻開發》專欄Part 3&#xff5c;Unity VR眼鏡端播放器開發與優化第一節&#xff5c;基于Unity的360全景視頻播放實現方案第二節&#xff5c;VR眼鏡端的開發適配與交互設計一、Unity XR開發環境與設備適配1.1 啟用XR Plugin Management1.2 配置OpenXR與平…

SQL進階之旅 Day 16:特定數據庫引擎高級特性

【SQL進階之旅 Day 16】特定數據庫引擎高級特性 開篇 在“SQL進階之旅”系列的第16天&#xff0c;我們將探討特定數據庫引擎的高級特性。這些特性通常為某些特定場景設計&#xff0c;能夠顯著提升查詢性能或簡化復雜任務。本篇文章將覆蓋MySQL、PostgreSQL和Oracle的核心高級…

c++算法學習4——廣度搜索bfs

一、引言&#xff1a;探索迷宮的智能方法 在解決迷宮最短路徑問題時&#xff0c;廣度優先搜索&#xff08;BFS&#xff09;是一種高效而優雅的算法。與深度優先搜索&#xff08;DFS&#xff09;不同&#xff0c;BFS采用"由近及遠"的搜索策略&#xff0c;逐層探索所有…

4.RV1126-OPENCV 圖像輪廓識別

一.圖像識別API 1.圖像識別作用 它常用于視覺任務、目標檢測、圖像分割等等。在 OPENCV 中通常使用 Canny 函數、findContours 函數、drawContours 函數結合在一起去做輪廓的形檢測。 2.常用的API findContours 函數&#xff1a;用于尋找圖片的輪廓&#xff0c;并把所有的數…

Qt多線程訪問同一個數據庫源碼分享(基于Sqlite實現)

Qt多線程訪問同一個數據庫源碼分享&#xff08;基于Sqlite實現&#xff09; 一、實現難點線程安全問題死鎖風險連接管理問題數據一致性性能瓶頸跨線程信號槽最佳實踐建議 二、源碼分享三、測試1、新建一個多線程類2、開啟多線程插入數據 一、實現難點 多線程環境下多個線程同時…

雙空間知識蒸餾用于大語言模型

Dual-Space Knowledge Distillation for Large Language Models 發表&#xff1a;EMNLP 2024 機構&#xff1a;Beijing Key Lab of Traffic Data Analysis and Mining 連接&#xff1a;https://aclanthology.org/2024.emnlp-main.1010.pdf 代碼&#xff1a;GitHub - songmz…

貪心算法應用:多重背包啟發式問題詳解

貪心算法應用&#xff1a;多重背包啟發式問題詳解 多重背包問題是經典的組合優化問題&#xff0c;也是貪心算法的重要應用場景。本文將全面深入地探討Java中如何利用貪心算法解決多重背包問題。 多重背包問題定義 **多重背包問題(Multiple Knapsack Problem)**是背包問題的變…

ES6 Promise 狀態機

狀態機&#xff1a;抽象的計算模型&#xff0c;根據特定的條件或者信號切換不同的狀態 一、Promise 是什么&#xff1f; 簡單來說&#xff0c;Promise 就是一個“承諾對象”。在ES6 里&#xff0c;有些代碼執行起來需要點時間&#xff0c;比如加載文件、等待網絡請求或者設置…

【Docker管理工具】部署Docker可視化管理面板Dpanel

【Docker管理工具】部署Docker可視化管理面板Dpanel 一、Dpanel介紹1.1 DPanel 簡介1.2 主要特點 二、本次實踐規劃2.1 本地環境規劃2.2 本次實踐介紹 三、本地環境檢查3.1 檢查Docker服務狀態3.2 檢查Docker版本3.3 檢查docker compose 版本 四、下載Dpanel鏡像五、部署Dpanel…

最新研究揭示云端大語言模型防護機制的成效與缺陷

一項全面新研究揭露了主流云端大語言模型&#xff08;LLM&#xff09;平臺安全機制存在重大漏洞與不一致性&#xff0c;對當前人工智能安全基礎設施現狀敲響警鐘。該研究評估了三大領先生成式AI平臺的內容過濾和提示注入防御效果&#xff0c;揭示了安全措施在阻止有害內容生成與…

docker中,容器時間和宿機主機時間不一致問題

win11下的docker中有個mysql。今天發現插入數據的時間不正確。后來發現原來是docker容器中的時間不正確。于是嘗試了各種修改&#xff0c;什么run -e TZ"${tzutil /g}"&#xff0c;TZ"Asia/Shanghai"&#xff0c;還有初始化時帶--mysqld一類的&#xff0c;…

uniapp實現的簡約美觀的星級評分組件

采用 uniapp 實現的一款簡約美觀的星級評分模板&#xff0c;提供絲滑動畫效果&#xff0c;用戶可根據自身需求進行自定義修改、擴展&#xff0c;純CSS、HTML實現&#xff0c;支持web、H5、微信小程序&#xff08;其他小程序請自行測試&#xff09; 可到插件市場下載嘗試&#x…

go語言的鎖

本篇文章主要講鎖&#xff0c;主要會涉及go的sync.Mutex和sync.RWMutex。 一.鎖的概念和發展 1.1 鎖的概念 所謂的加鎖和解鎖其實就是指一個數據是否被占用了&#xff0c;通過Mutex內的一個狀態來表示。 例如&#xff0c;取 0 表示未加鎖&#xff0c;1 表示已加鎖&#xff…

Ubuntu 服務器軟件更新,以及常用軟件安裝 —— 一步一步配置 Ubuntu Server 的 NodeJS 服務器詳細實錄 3

前言 前面&#xff0c;我們已經 安裝好了 Ubuntu 服務器系統&#xff0c;并且 配置好了 ssh 免密登錄服務器 &#xff0c;現在&#xff0c;我們要來進一步的設置服務器。 那么&#xff0c;本文&#xff0c;就是進行服務器的系統更新&#xff0c;以及常用軟件的安裝 調整 Ubu…

如何從零開始建設一個網站?

當你沒有建站的基礎和建站的知識&#xff0c;那么應該如何開展網站建設和網站管理。而今天的教程是不管你是為自己建站還是為他人建站都適合的。本教程會指導你如何進入建站&#xff0c;將建站的步驟給大家分解&#xff1a; 首先我們了解一下&#xff0c;建站需要那些步驟和流程…

網絡可靠性的定義與核心要素

網絡可靠性&#xff08;Network Reliability&#xff09;是指網絡系統在特定時間范圍內持續提供穩定、無中斷、符合預期性能的服務能力。其核心目標是確保數據能夠準確、完整、及時地傳輸&#xff0c;即使在部分故障或異常情況下仍能維持基本功能。 1. 網絡可靠性的核心指標 衡…

GpuGeek如何成為AI基礎設施市場的中堅力量

AI時代&#xff0c;算力基礎設施已成為支撐技術創新和產業升級的關鍵要素。作為國內專注服務算法工程師群體的智算平臺&#xff0c;GpuGeek通過持續創新的服務模式、精準的市場定位和系統化的生態建設&#xff0c;正快速成長為AI基礎設施領域的中堅力量。本文將深入分析GpuGeek…

【Qt】Bug:findChildren找不到控件

使用正確的父對象調用 findChildren&#xff1a;不要在布局對象上調用 findChildren&#xff0c;而應該在布局所在的窗口或控件上調用。

【Linux網絡編程】傳輸層協議TCP,UDP

目錄 一&#xff0c;UDP協議 1&#xff0c;UDP協議的格式 2&#xff0c;UDP的特點 3&#xff0c;面向數據報 4&#xff0c;UDP的緩沖區 5&#xff0c;UDP使用注意事項 6&#xff0c;基于UDP的應用層協議 二&#xff0c;對于報文的理解 三&#xff0c;TCP協議 1&…