当前位置: 首页 > news >正文

深入解析: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.使用合适的数据结构


使用场景:

说明:

  • 选择合适的数据结构可以提高程序的性能和内存利用率。
  • 在使用大型数据集合时,数据结构的选择尤为关键。

示例: 

// 使用 List
List<int> numbersList = new List<int> { 1,
2,
3,
4,
5 };// 使用 Array
int[] numbersArray = new int[] { 1,
2,
3,
4,
5 };// 当数据量固定时,Array 比 List 更节省内存Dictionary<int,
string> employeeDirectory = new Dictionary<int,
string>();employeeDirectory[1002] = "Robert";//快速查找更新,字典更快捷

3.使用 struct 代替 class(在合适的场景)


使用场景:

说明:

  • 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 替代字符串连接


使用场景:

说明:

  • 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 语句管理资源


使用场景:

说明:

  • 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.zskr.cn/news/16105.html

相关文章:

  • 2025声级计厂家最新权威推荐排行榜单! 数字声级计,精密声级计,防爆声级计,手持式声级计,剂量声级计公司推荐!
  • python中使用高并发分布式队列库celery的那些坑 - 指南
  • 在AI技术唾手可得的时代,挖掘新需求成为核心竞争力——某知名计算机控制AI框架需求洞察
  • 无人机桥梁3D建模、巡检、检测的航线规划 - 详解
  • mac 下修改本机hosts
  • 【光照】Unity如何在Cubemap中采样反射信息?
  • 深入解析:[论文阅读]Poisonprompt: Backdoor attack on prompt-based large language models
  • 箭头
  • 2025广告喷绘公司最新推荐榜单, 覆盖广告喷绘广告牌,广告喷绘写真,广告喷绘广告牌写真,广告喷绘门头服务!
  • 实用指南:24.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--认证微服务
  • 详细介绍:STM32 串口通信①:USART 全面理解 + 代码详解
  • 2025夹丝玻璃厂家最新企业品牌推荐排行榜,艺术夹丝玻璃,淋浴房夹丝玻璃,极简门夹丝玻璃,金属夹丝玻璃公司推荐!
  • 详细介绍:性能优化 - 案例篇:缓存_Guava#LoadingCache设计
  • 2025年X射线管厂家最新企业品牌推荐排行榜,工业用金属陶瓷,波长色散荧光分析,应力衍射分析,管板角焊缝,轮胎检测,辐照,固定阳极波纹陶瓷,测厚,食品检测 X 射线管公司推荐
  • 深入解析:Guava限频器RateLimiter的使用示例
  • Photoshop 在线网页版?是的,它来了!免费使用指南
  • 鲲鹏Arm+麒麟V10 K8s 离线部署教程 - 教程
  • 线段树模板1
  • 20多年前李敖告訴你美國為什麼不可靠?
  • 2025数控铣床厂家最新企业品牌推荐排行榜, 双头数控铣床,双面数控铣床,龙门数控铣床,双侧数控铣床推荐这十家公司!
  • 题解:2025.10.信友队.智灵班选拔面试题目
  • MX WEEK4
  • 实用指南:【25软考网工】第十章 网络规划与设计(1)综合布线
  • 深入解析:Java基础(二):八种基本数据类型详解
  • 物理_备忘
  • 详细介绍:静态资源js,css免费CDN服务比较
  • 在AI技术唾手可得的时代,挖掘JavaScript学习资源的新需求成为关键
  • 读人形机器人31未来30年
  • 【java面试】redis篇 - 指南
  • NLP学习路线图(十四):词袋模型(Bag of Words) - 详解