频繁访问数据库,该如何释放内存?

蜗牛学编程 2020-08-20 10:37:29
各位老师,小弟学习编程过程中有几个疑问,求教老师们:
我在编写一个系统,因为基本上都是对数据库操作,因此里面基本上都是SQL语句,并有datagridview和listview,绑定数据源的combobox等针对数据库的控件,伴随有很多增删查改之语句(貌似我现在每一步都会对数据库进行访问,这样正确吗?)[
问题来了:我每次对数据库操作完后,除了关闭数据库连接外,还需要设置disposed,释放各种命令中的内存吗?譬如dataset,datatable,ExecuteNonQuery,ExecuteReader等,他们会在关闭连接后还占用内存吗?如果不释放,是不是时间长了就会耗尽内存,让运行速度变得很慢?
查了一些资料,众多纷纭,有说不需要,现在C#已经设置成系统会自动回收。有说需要,但dispose还不行,要设置null。也有的说某些代码需要释放,譬如dataset,datatable和DataAdapter,有些不需要,close即可。
我有点晕了,不知道哪个是正确。我的电脑内存16G的,不过是当成公共电脑给单位使用,数据库大概不会超过1G,同时访问人数约几十人。这内存够吗?

另外,假设有20个数据:1~20,如何才能每次点击,从中生成一个随机,但不重复的数据呢?例如5,9,12,6,8,19.。。。。。点击10次,就会有10个不同的数据。
这代码该如何写吗?尝试良久,效果不理想,道行太浅,请老师们帮忙哈。
...全文
5589 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
shawn_yang 2020-08-25
  • 打赏
  • 举报
回复
using {}
蜗牛学编程 2020-08-22
  • 打赏
  • 举报
回复
[quote=引用 10 楼 以专业开发人员为伍 的回复:]提出问题很好。即使是在流水线上的工人,也可以有工程师的梦想,但是首先就是要有工程师的思路。就好像有人被问到说“你为什么吃饭总是吧唧嘴?"时,他回答说“因为我爸我妈就吧唧嘴,我以为要吃饭就必须先吧唧嘴”一样,动不动就纠结“释放内存”是典型地用“响亮的且正确的废话”来说明问题,而不是基于测试。不要轻信任何人,你要自己写测试,看看你不显式调用 Dispose 能不能导致出错?!你就知道那种“永远正确”的解释是否真正靠谱。 [quote] 嗯,我已经测试过好久,貌似我直接调用close对速度来说基本没什么变化。更没有任何的相关的报错/ 但我不确定是因为我的数据量少还是因为只有我一个人在测试,没有大规模大范围测试所以才没问题。所以才上来请教一下各位老师。因为一旦系统正式运行,发现这是个问题再去改就很麻烦了
蜗牛学编程 2020-08-22
  • 打赏
  • 举报
回复

//按顺序准备20道考题
List<int> allQues = new List<int>(20);
int quesCount = 1;
while (quesCount <= 20)
{
    allQues.Add(quesCount);
    quesCount++;
}

//新的随机的考题
int[] newQues = new int[20];
Random rd = new Random();
for (int i = 0; i < 20; i++)
{
    //随机从题库中选,选中之后从题库中移走
    int randomIdx = rd.Next() % allQues.Count;
    newQues[i] = allQues[randomIdx];
    allQues.RemoveAt(randomIdx);
}

//打印出来看看
for(int i = 0; i < 20; i++)
{
    Console.WriteLine(newQues[i]);
}
[/quote] 这好像不行啊。我把newQues[i]输出到textBox中,发现经常出现重复的数值。
  • 打赏
  • 举报
回复
“我有点晕了,不知道哪个是正确。我的电脑内存16G的,不过是当成公共电脑给单位使用,数据库大概不会超过1G,同时访问人数约几十人。这内存够吗?”

提出问题很好。即使是在流水线上的工人,也可以有工程师的梦想,但是首先就是要有工程师的思路。就好像有人被问到说“你为什么吃饭总是吧唧嘴?"时,他回答说“因为我爸我妈就吧唧嘴,我以为要吃饭就必须先吧唧嘴”一样,动不动就纠结“释放内存”是典型地用“响亮的且正确的废话”来说明问题,而不是基于测试。不要轻信任何人,你要自己写测试,看看你不显式调用 Dispose 能不能导致出错?!你就知道那种“永远正确”的解释是否真正靠谱。



对于 Random 对象实例的问题,你应该自己查一下资料。每一个随即发生器都维系着一个内部的“种子”,每一次获取 Next 值的时候都更新这个种子用于下一次产生随机值。而当初始化一个新的 Random 对象时,这个种子值默认是使用当前的时钟的值来产生的。所以不要“几乎同时”创建多个 Random 对象分别产生随机数,而要用“一个”对象来产生多个随机数,甚至你可以声明一个 static 的 Random 对象来反复使用,才能避免种子重复。
  • 打赏
  • 举报
回复
“释放各种命令中的内存”这其实没什么错误,但是却是最响亮的“空话”。因为调用 IDisposable 接口方法的原因并不真正在于此。上面已经有人说过了,对于 .net 和 java 这类有着非常靠谱的虚拟机保护的系统来说,非常稳定地,它会在几秒钟内就反复自动调用 GC来开始清理不再需要占用的内存垃圾。你不去纠结什么“释放内存”的话,系统也会自动做这些。

我们面试的时候就要问问应聘者,“为什么要针对 DBConnection 调用 Dispose,而不用针对 DBCommand 和 DBDataReader 等等对象调用Dispose 呢?”。问这些问题就知道技术方向。有不少人只知道道听途说。

调用 DbConnection 的 IDisposeable 接口方法是因为几乎所有 ADO.NET 的连接 provider 都是基于连接池机制而设计的,也就是说它可以用很少的(例如10个)物理连接来自动缓冲给成千上万的(几乎)并发客户端共用。如果你不及时调用 Close 方法,那么逻辑连接就要等到几秒钟以后 GC 过程中调用 Dispose 方法时才能被间接调用到 Close,而几秒钟的延迟就可能经常遇到“连接池满”的系统异常。
65号腕 2020-08-22
  • 打赏
  • 举报
回复
引用 6 楼 蜗牛学编程 的回复:
[quote=引用 1 楼 65号腕 的回复:]1.通常来说只要及时关闭数据库连接就行了 2.数据库那么小,16G一般是足够用的,除非你的并发性特别高,这个也没什么固定的标准的。 3.不明白你的使用场景,按你的描述,把1-20放进数组,然后随机取,取完移走不就行了。
我是准备写一个考试系统,里面有20道题,每个人进去后,打乱20道题的顺序,让每个人的答题顺序都不一样。 不太会用数组,老师可否帮忙写一下代码?多谢多谢~~~[/quote] 数组不会用,那你得去学学C#的入门教程以及编程的基本知识了,别一上来就撸系统。以下代码仅供参考:

//按顺序准备20道考题
List<int> allQues = new List<int>(20);
int quesCount = 1;
while (quesCount <= 20)
{
    allQues.Add(quesCount);
    quesCount++;
}

//新的随机的考题
int[] newQues = new int[20];
Random rd = new Random();
for (int i = 0; i < 20; i++)
{
    //随机从题库中选,选中之后从题库中移走
    int randomIdx = rd.Next() % allQues.Count;
    newQues[i] = allQues[randomIdx];
    allQues.RemoveAt(randomIdx);
}

//打印出来看看
for(int i = 0; i < 20; i++)
{
    Console.WriteLine(newQues[i]);
}
threenewbee 2020-08-21
  • 打赏
  • 举报
回复
.net自己管理内存,你访问数据库,只要调用结束调用close关闭或者放在using块就可以了。不需要释放。
16GB内存的电脑,对于一个access数据库的小软件,基本可以认为内存是无限的。
C#是2002年问世的,那时候的电脑大约只有0.1~0.2GB的内存。如果你觉得16GB都不够,那时候的人不要写程序了。
蜗牛学编程 2020-08-21
  • 打赏
  • 举报
回复
引用 1 楼 65号腕 的回复:
1.通常来说只要及时关闭数据库连接就行了 2.数据库那么小,16G一般是足够用的,除非你的并发性特别高,这个也没什么固定的标准的。 3.不明白你的使用场景,按你的描述,把1-20放进数组,然后随机取,取完移走不就行了。
我是准备写一个考试系统,里面有20道题,每个人进去后,打乱20道题的顺序,让每个人的答题顺序都不一样。 不太会用数组,老师可否帮忙写一下代码?多谢多谢~~~
wanghui0380 2020-08-21
  • 打赏
  • 举报
回复
对于新手来说我们建议“远离博客园”,至少在你无法分清楚,无法评价的时候,别看,少看。 就如同开车,打游戏,下棋。开始就看高手开车,高手下棋,高手打游戏??学么,学不来,不仅学不来,还容易学出事 废话不说,现在的你,我们不会给你搞啥,炫技讲啥原理,弄啥“血案” 对于现在的你,我们只能像教练那样,让你上车调整座椅,系好安全带。 so using() { } 就是你要做的事情,至于其他的,边上有性能测试,自己看内存,cpu,gc,看看“表盘”就知道你超速没 一句话--------按逻辑做,按标准做,别按xx园各种所谓的‘高级技巧,高端手段,血案做’,先能上路开稳了,在来谈啥漂移
小白卟白 2020-08-21
  • 打赏
  • 举报
回复
用using 及时关闭数据库 也会自动释放; using (sqlconnection conn =new sqlconnection("数据库字符串") ){ conn.open(); //自己的代码 //可以再加上 GC释放内存 }
postfxj 2020-08-21
  • 打赏
  • 举报
回复
1.确保释放数据库连接资源的两种方式如下: a.使用try...catch...finally语句块,在finally块中关闭连接; b.使用using语句块,无论如何退出,都会自动关闭连接; 2.最好的方法是组合使用以上两种方式。 using System; using System.Data.SqlClient; namespace Magci.Test.DataAccess { class Program { static void Main(string[] args) { string source = @"server=.\sqlexpress; integrated security=SSPI; database=msdb"; SqlConnection conn = null; //使用try块处理 try { conn = new SqlConnection(source); conn.Open(); //Do something } catch (Exception e) { //Do something with the exception } finally { conn.Close(); } //使用using块处理 using (conn = new SqlConnection(source)) { conn.Open(); //Do something } //两种组合方式 try { using (conn = new SqlConnection(source)) { conn.Open(); //Do something conn.Close(); } } catch (Exception e) { //Do something with the exception } } } }
yuwentao4761901 2020-08-21
  • 打赏
  • 举报
回复
其实并不会!只要使用完即使关闭连接,释放资源就不会有什么问题!而且.NET自带GC回收优化系统内存!如果是担心数据库不够用,可以换成性能更强大的 Linux系统+MySQL、PostgreSQL或者Oracle数据库,性能远超Windows+SQL Server
65号腕 2020-08-20
  • 打赏
  • 举报
回复
1.通常来说只要及时关闭数据库连接就行了 2.数据库那么小,16G一般是足够用的,除非你的并发性特别高,这个也没什么固定的标准的。 3.不明白你的使用场景,按你的描述,把1-20放进数组,然后随机取,取完移走不就行了。

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧