C#管理大量耗时的线程,内存占用严重

我水平有限,在socket方面不在行,一直让我对socket没信心的是两个方面,
第一:socket异常时有些捕获不到,就是没法准确判断连接是否已经断开;
第二:重点,就是每个客户端连接过来的时候都需要开辟一个新的线程去处理客户发来的消息,如果客户过多势必导致线程数量不断增加,内存也会飙升,怎么有效的管理这些线程,让内存更加稳定呢, 或者说就socket这块大量用户连接的时候有没有更好的处理方法, 线程池不适合用来做耗时的任务,大家懂的

在你的表述中,“线程池不适合用来做耗时的任务”是最大误区
1)你一定看到过System.Net.Socket类中有很多BeginXXX / EndXXX的方法,例如Socket.BeginReceiveFrom和Socket.EndReceiveFrom,这些函数统称为异步函数。而异步函数操作的基础恰恰就是线程池。对Socket通信而言,微软提供的异步操作正是利用线程池中I/O线程,目的就是为了提高Socket I/O性能并简化内存管理的!
2)如果对异步操作感到头晕,在处理Socket操作时可以使用“显式线程”方法,即按以下方法启动处理线程:
System.Thread t = new System.Thread(你的处理函数);
t.IsBackground = true; //这个设置尤其重要!!!!!
t.Start();
一定要注意将线程设置为后台线程!
3)你一定知道系统每次启动线程和销毁线程时都会导致很大的开销。当你的程序频繁的启动、销毁线程,必然会导致程序很“卡”;正是由于这个缘故,微软才搞了一个“线程池”。因为线程中的线程都是“启动完毕的”(这样表述虽不确切,但没有错),一旦你将异步处理函数“挂接”的线程池中的空闲线程上即可以执行你要的操作。而且,额外的好处是你根本不用去管理线程池中的线程(真正的“零”管理)
4)处理“耗时的操作”特别是涉及诸如Socket I/O 耗时操作,最佳的处理方法是利用后台线程(如果需要,同时配合以自定义事件event),这是增加用户体验不二法门哦~~追问

就是说 在简单的Socket编程中,用户进入跟处理用户信息全部用异步来操作是吗,不需要用“显式线程”来处理么? 这样做仅仅是为了让系统自动回收垃圾吗 还是有别的好处?

另外在别的地方看到异步处理是不是有个数限制,比如能异步接收64个客户进入,

追答

你说的 "用户进入跟处理用户信息"中的用户信息是通过Socket传递的吗?如果是,在异步回调中处理 。总之,涉及到Socket的操作均采用异步处理或后台线程处理。
曾经编写一个Socket UDP程序,同时处理1000多个客户端,双核CPU,2G内存。运行过程中CPU平均占用率不超过12%

追问

我一直是用的isBackGround的, 可能内存飙升不是线程的问题吧,

追答

嗯,应该不是线程的问题。导致内存使用飙升的根本原因肯定是处理过程中生成大量的对象并没有释放。这里说的“释放”与“垃圾回收”不是同一个概念。“释放”是指定一个对象引用的“释放”。但垃圾回收规则,只有对一个对象的所有引用都释放了才能进行垃圾回收。反过来说,只有对象存在引用,就不会做垃圾回收。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-09-24
Windows下参考完全端口,也叫iocp;Linux下参见Epoll
第2个回答  2013-09-24

你的问题涉及很多方面。帮你清理一下,

    socket 的追踪问题,没法准确判断连接是否已经断开,今天技术问题很容易解决。

    多线程问题,每个客户端连接过来的时候都需要开辟一个新的线程去处理客户发来的消息。

    耗时的任务, 感觉关键在于耗时的任务,因为耗时的线程确实会很快消耗掉所有的线程池。

首先,耗时是什么造成的,如果是硬盘读写,能否用cache解决?如果是网络问题,能否call back? 如果是数据库问题,能否用cluster?如果是CPU问题,能否采用web farm?

本回答被网友采纳

C#管理大量耗时的线程,内存占用严重
1)你一定看到过System.Net.Socket类中有很多BeginXXX \/ EndXXX的方法,例如Socket.BeginReceiveFrom和Socket.EndReceiveFrom,这些函数统称为异步函数。而异步函数操作的基础恰恰就是线程池。对Socket通信而言,微软提供的异步操作正是利用线程池中I\/O线程,目的就是为了提高Socket I\/O性能并简化内存管理的!

C#管理大量耗时的线程,内存占用严重
1.socket 的追踪问题,没法准确判断连接是否已经断开,今天技术问题很容易解决。2.多线程问题,每个客户端连接过来的时候都需要开辟一个新的线程去处理客户发来的消息。3.耗时的任务, 感觉关键在于耗时的任务,因为耗时的线程确实会很快消耗掉所有的线程池。首先,耗时是什么造成的,如果是硬盘读写,能否...

C# 程序内存占用过高
通常,2)是导致内存占用过大的原因!请仔细检查是否出现了对象的循环引用。

c#线程开太多cpu占用高
任何一个线程占CPU高都会导致整体CPU高,跟数量无关。

c#多线程开发系统内存莫名增加?
一种解释(猜测)是,.net内存回收机制回收的内存虽然交给了操作系统,但是操作系统并不一定马上把它们清理到“可用内存”中去,而是很有可能继续保留以便当前程序再次申请同样大小、用途的内存块,这样可以大大提高性能。——以上是参考Linux系统的内存管理模块Slab分配器原理进行的推测,Windows机制虽然很可能...

c# winForm关于内存占用的问题
解决假死的问题,可以用多线程或异步委托,网上有很多例子这里就不详细说明了。内存占用量大,可以使用GC提供的方法进行对象释放和内存清理,最需要注意的是代码中不要产生大量的垃圾,比如说大量使用string+string就很容易产生大量的内存垃圾。

...线程的性能,我的程序里面由于开了比较多的线程,比较卡,我想监视下...
你所说的性能包含哪些?内存占用?CPU占用?还是运行时间?线程占用资源?那个很简单啊,你把Sizeof用上,把你每个对象都Sizeof出来,ok了。

c#CPU占用太高,可以从哪些方面优化
可以考虑将程序占用的线程或核心数进行手动分配 其次降低除了C#之外的其他软件使用,最大腾出可用系统资源

c#listview占用内存大
1、使用虚拟模式,ListView支持虚拟模式,只在需要显示项时才加载数据,减少内存占用。2、如果数据量较大,可以将数据进行分页处理,每次只显示一页数据,这样可以减小内存占用。3、可以使用异步加载技术,在后台线程中加载数据,避免阻塞主线程和过度占用内存。

c# 做的C\/S程序,在占的内存资源如何释放掉?
C# 内存管理是基于优化的收集方式,引入了代的机制(共分3代0、1、2),当0代充满时或内存紧张时,垃圾收集器会挂起当前线程自动收集0代没有被引用的新建的对象,1代充满时收集1代,2代充满时收集2代。见意最好不要手动进行GC的收集,这样会带来不必要的系统资源的浪费。如果不进行人工干预内存太...

相似回答