提问人:Ben Jamin 提问时间:10/28/2023 最后编辑:Ben Jamin 更新时间:10/28/2023 访问量:135
在处理大字符串时,有没有办法在 C# 中手动释放内存?
Is there a way manually release memory in C# when handling large strings?
问:
目前,我正在做一个需要从套接字连接接收大量数据的项目。该实现是用 C++ 编写的,我正在使用 C# 包装器来处理连接。在包装器中,我使用 Encoding.UTF8.GetString() 从 byte[] 转换为字符串。问题来了,在 C# 中没有办法释放字符串内存,因此内存消耗总是越来越高。GC 无法收集内存,并且达到了不可接受的高级别。
我编写了一个随机字符串生成器来模仿这种行为:
Random rand = new Random();
// Choosing the size of string
int stringlen = 64 * 1024;
int round = 100000;
int randValue;
StringBuilder str = new(stringlen);
char letter;
for (int j = 0; j < round; j++)
{
for (int i = 0; i < stringlen; i++)
{
// Generating a random number.
randValue = rand.Next(0, 26);
// Generating random character by converting
// the random number into character.
letter = Convert.ToChar(randValue + 65);
// Appending the letter to string.
str.Append(letter);
}
}
下面是 dotTrace 中的内存使用情况:
有没有办法解决这个问题?
我希望我们可以像在cpp中一样使用delete()或free()方法来手动释放字符串
[编辑]我注意到我犯了一个错误,我没有清除 StringBuilder。为了更清楚起见,我修改了以下代码:
using System.Text;
namespace TestBigString
{
internal class Program
{
private static void Main()
{
const int round = 10000;
StringBuilder sb = new();
for (var j = 0; j < 1000; j++)
{
for (var i = 0; i < round; i++)
{
sb.Append(RandomString());
}
sb.Clear();
}
}
private static string RandomString()
{
Random rand = new();
// Choosing the size of string
const int stringLen = 64 * 1024;
StringBuilder str = new(stringLen);
for (var i = 0; i < stringLen; i++)
{
// Generating a random number.
var randValue = rand.Next(0, 26);
// Generating random character by converting
// the random number into character.
var letter = Convert.ToChar(randValue + 65);
// Appending the letter to string.
str.Append(letter);
}
return str.ToString();
}
}
}
由于每轮都生成了 64KB 的字符串,并且我运行了 10000 轮,因此我预计只有大约 640MB 的内存。然而,我得到的远不止这些。
答: 暂无答案
评论