c#线程与内存之间的处理

菜二 2020-07-09 08:09:22
我不停的开启新的线程,线程方法运行的时间比开启线程的时间间隔要长。 导致线程在不断增加的同时,内存也在不断增长,cpu跟内存都会爆。 后来优化了线程方法运行时间,以及内存处理。但是还是面临cpu经常100%导致卡死,如果用线程池控制只开队列最多开4个线程,cpu稳定运行,但是内存就会溢出。 这时候用什么好的方式处理?
...全文
3986 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2020-07-12
  • 打赏
  • 举报
回复
你自己给一个基本检查,我们只能先开片药,试试看。 https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream ps:同上线程的确可内存没啥关系,并不需要参考那些整天看博客园的博客论。在这里我们已经无数次证明你就是同时开1亿一个只执行1ms的简单线程都没问题。 问题不在线程,问题在你new了无数个stream,我们都不说啥线程不线成。你自己看看俺们就一个单线程 new byte[1024*1024*1024]连续系统能让你new几次?
jhonsonzhang 2020-07-11
  • 打赏
  • 举报
回复
抛弃线程,使用 Async Task,再加个回调处理。不可能出现你说的这种情况,另外我感觉你图像处理的代码貌似有问题,你异步的话,代码的错误进行了捕捉吗?
菜二 2020-07-11
  • 打赏
  • 举报
回复
我在仔细说一下流程叭:我是接收相机给我的图像,一秒23帧,每个图像都要进行处理,也就相当于一帧图像开一个线程,线程方法里面是处理图像的算法,线程结束之后图像也会处理释放掉。线程方法处理图像时间不一样,最快的时候3ms就处理结束,最慢500ms都有。这就导致线程开启太多,cpu处理不了,然后图像处理太慢导致线程方法阻塞,没有及时释放图像,从而导致内存爆炸
threenewbee 2020-07-09
  • 打赏
  • 举报
回复
可以使用队列、线程池,限制并发的线程的数量
datafansbj 2020-07-09
  • 打赏
  • 举报
回复
机器运算能力、内存容量就那么大,如果偏要让其处理超过自己能力的事情,肯定资源会不足了。
线程池只能缓解优化调度,不能彻底解决这种问题。
也许增加CPU、增加内存是最直接、最暴力的解决办法。
正怒月神 2020-07-09
  • 打赏
  • 举报
回复
如果没有共享变量。那么就可能是大对象的问题。 这个需要你优化大对象。或者增加线程内存大小。
正怒月神 2020-07-09
  • 打赏
  • 举报
回复
1 使用线程池,应该没问题 2 内存溢出,你检查一下是否存在共享变量没有回收。
wanghui0380 2020-07-09
  • 打赏
  • 举报
回复
“医生,我头疼” 医生说“去做检查先” ------------------------------------- 这里一样,我们不会像博客园那样,一说头疼就是血案,然后说“吃阿司匹林”,所以我们现在不会给你开药。 你得先用vs自己得诊断工具,去实际探测,到底是什么占了内存。
耗子哭死猫 2020-07-09
  • 打赏
  • 举报
回复
我记的线程池 执行任务,执行完了反馈回来可以再执行下一个,完全可以解决资源滥用的情况
datafansbj 2020-07-09
  • 打赏
  • 举报
回复
引用 8 楼 闭包客 的回复:
内存溢出和线程的处理没有绝对的联系,只能说线程执行的任务本身对资源的回收处理是有问题的。


不敢苟同,线程本身就要占用资源,短时间启用大量线程时,系统不能同时执行所有线程(CPU核心数有限),多余的线程数据会缓存在系统内存中去排队,等排到了再执行。如果这种线程积累过多,表现结果是 CPU 占用不高,但是内存暴涨。
闭包客 2020-07-09
  • 打赏
  • 举报
回复
内存溢出和线程的处理没有绝对的联系,只能说线程执行的任务本身对资源的回收处理是有问题的。
exception92 2020-07-09
  • 打赏
  • 举报
回复
我不停的开启新的线程
-》线程很浪费资源,过多的线程会导致cpu使用率暴增。最好看一下cpu核数,参考#6的建议限制并发线程数量,查询Task用法。
当然内存暴增也可能不只是线程造成的,比如非托管资源占用释放不及时,没有使用缓存等等。
内容简介 您想淋漓尽致地发挥多核计算机系统的处理能力吗?《C#并行编程高级教程:精通NET 4 Parallel Extensions》将帮助您实现这一夙愿。这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合地使用高级Intel工具与C#,并指导您巧妙使用新引入的轻型协调结构来开发自己的解决方案并解决最棘手的并发编程问题。 主要内容 ◆介绍如何基于新Task Parallel Library和.NET 4设计稳定的可扩展并行应用程序。 ◆讲解命令式数据并行、命令式任务并行、并发集合以及协调数据结构。 ◆描述PLINQ高级声明式数据并行。 ◆讨论如何使用新的Visual Studio 2010并行调试功能来调试匿名方法、任务和线程。 ◆演示如何对数据源进行分区,以便在不同任务和线程之间合理分配工作负荷。 作者简介 Caston C.Hillar是一位独立软件咨询师,自1997年起便一直从事并行编程、多处理器和多核领域的研究,Gaston拥有使用C#和.NET Framework来设计和开发各种复杂并行解决方案的丰富经验,曾于2009年荣膺Intel Black Belt Software Developer奖。 目录 第1章 基于任务的程序设计 1.1 使用共享内存的多核系统 1.1.1 共享内存多核系统与分布式内存系统之间的区别 1.1.2 并行程序设计和多核程序设计 1.2 理解硬件线程和软件线程 1.3 理解Amdahl法则 1.4 考虑Gustafson法则 1.5 使用轻量级并发模型 1.6 创建成功的基于任务的设计 1.6.1 以并发的思想指导设计 1.6.2 理解交错并发、并发和并行之间的区别 1.6.3 并行化任务 1.6.4 尽量减少临界区 1.6.5 理解多核并行程序的设计原则 1.7 为NUMA架构和更高的可扩展性做好准备 1.8 判断是否适合并行化 1.9 小结 第2章 命令式数据并行 2.1 加载并行任务 2.1.1 System.Threading.Tasks.Parallel类 2.1.2 Parallel.Invoke 2.2 将串行代码转换为并行代码 2.2.1 检测可并行化的热点 2.2.2 测量并行执行的加速效果 2.2.3 理解并发执行 2.3 循环并行化 2.3.1 Parallel.For 2.3.2 Parallel.ForEach 2.3.3 从并行循环中退出 2.4 指定并行度 2.4.1 ParallelOptions 2.4.2 计算硬件线程 2.4.3 逻辑内核并不是物理内核 2.5 通过甘特图检测临界区 2.6 小结 第3章 命令式任务并行 3.1 创建和管理任务 3.1.1 System.Threading.Tasks.Task 3.1.2 理解Task状态和生命周期 3.1.3 通过使用任务来对代码进行并行化 3.1.4 等待任务完成 3.1.5 忘记复杂的线程 3.1.6 通过取消标记取消任务 3.1.7 从任务返回值 3.1.8 TaskCreationOptions 3.1.9 通过延续串联多个任务 3.1.10 编写适应并发和并行的代码 3.2 小结 第4章 并发集合 4.1 理解并发集合提供的功能 4.1.1 System.Collections.Concurrent 4.1.2 ConcurrentQueue 4.1.3 理解并行的生产者-消费者模式 4.1.4 ConcurrentStack 4.1.5 将使用数组和不安全集合的代码转换为使用并发集合的代码 4.1.6 ConcurrentBag 4.1.7 IProducerConsumerCollection 4.1.8 BlockingCollection 4.1.9 ConcurrentDictionary 4.2 小结 第5章 协调数据结构 5.1 通过汽车和车道理解并发难题 5.1.1 非预期的副作用 5.1.2 竞争条件 5.1.3 死锁 5.1.4 使用原子操作的无锁算法 5.1.5 使用本地存储的无锁算法 5.2 理解新的同步机制 5.3 使用同步原语 5.3.1 通过屏障同步并发任务 5.3.2 屏障和ContinueWhenAll 5.3.3 在所有的参与者任务中捕捉异常 5.3.4 使用超时 5.3.5 使用动态数目的参与者 5.4 使用互斥锁 5.4.1 使用Monitor 5.4.2 使用锁超时 5.4.3 将代码重构为避免使用锁 5.5 将自旋锁用作互斥锁原语 5.5.1 使用超时 5.5.2 使用基于自旋的等待 5.5.3 自旋和处理器出让 5.5.4 使用volatile修饰符 5.6 使用轻量级的手动重置事件 5.6.1 使用ManualResetEventSlim进行自旋和等待 5.6.2 使用超时和取消 5.6.3 使用ManualResetEvent 5.7 限制资源的并发访问 5.7.1 使用SemaphoreSlim 5.7.2 使用超时和取消 5.7.3 使用 Semaphore 5.8 通过CountdownEvent简化动态fork和join场景 5.9 使用原子操作 5.10 小结 第6章 PLINQ:声明式数据并行 6.1 从LINQ转换到PLINQ 6.1.1 ParallelEnumerable及其AsParallel方法 6.1.2 AsOrdered和orderby子句 6.2 指定执行模式 6.3 理解PLINQ中的数据分区 6.4 通过PLINQ执行归约操作 6.5 创建自定义的PLINQ聚合函数 6.6 并发PLINQ任务 6.7 取消PLINQ 6.8 指定所需的并行度 6.8.1 WithDegreeOfParallelism 6.8.2 测量可扩展性 6.9 使用ForAll 6.9.1 foreach和ForAll的区别 6.9.2 测量可扩展性 6.10 通过WithMergeOptions配置返回结果的方式 6.11 处理PLINQ抛出的异常 6.12 使用PLINQ执行MapReduce算法 6.13 使用PLINQ设计串行多步操作 6.14 小结 第7章 Visual Studio 2010的任务调试能力 7.1 充分利用多显示器的支持 7.2 理解并行任务调试器窗口 7.3 查看Parallel Stacks图 …… 第8章 线程池 第9章 异步编程模型 第10章 并行测试和调优 第11章 向量化、SIMD指令以及其他并行库 附录A .NET 4中与并行相关的类图 附录B 并发UML模型 附录C Parallel Extensions Extras

110,534

社区成员

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

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

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