由于自己的设计失误,自己居然脑残的把tcp连接作为用户登录的标志,所以每次客户端连接服务端,我都在服务端保留和客户端通信的socket和input和output流,发送消息则用这两个节点流的处理流,用完后也不对处理流对象进行代码的显示关闭(因为关闭处理流,处理流对象会调用它包装的节点流对象的关闭,进而关闭socket),,,,,下次通讯在将input和和output进行处理流包装,却仍不能关闭处理流,,,,,自己试过了这样确实可以,,,,但是我却担心一个问题了,一旦用户量大,通讯多,那么多处理流没关,会不会造成内存泄露(java回收机制貌是是不回收流资源的)
后来自己安慰自己:其实处理流只是一个类,类里面有节点流的引用,并没有节点流对象,它的函数是调用节点流实现的。仅仅是对节点流的一个包装,并不是实际与硬件相关的流,不晓得自己猜测的对不对,求高人指点。

解决方案 »

  1.   

    用的nio非阻塞socket,selector监视登录用户的socket,一有情况就开个线程放到线程池中运行,线程主要是处理用户的信息,加了点自己定义的通讯协议。
      

  2.   

    NIO的话,可以一条线程管理多个连接,这样可以节省线程数,因为线程数的限制一般只有一千多到几千个(JVM内存越大,可创建线程数越少),远低于 可供消耗的文件句柄数。那么基本上也没太大问题了。
      

  3.   

    恩,是的,我就是这样做的,用map保存socket和流,只有客户端来连接或登录或通讯才开设线程去处理,处理完就返回。
      

  4.   


    这个又显得有点浪费了,创建线程是需要代价的。建议两种做法:
    1、固定线程组,每个线程负责维护比如 50 条连接;
    2、用Java自带线程池,设置好固定数,有事件就扔给线程池去玩。前者更好的优化处理效率,后者实现简单。
      

  5.   

    Nice。 我没有啥其它建议了,看看有无其它人给你建议了。
      

  6.   

    使用长连接通信,服务端所承受的连接数,比如较少。
    长连接,一般是用来处理大批量数据传输而存在的。
    如果只是小数据量的传输,推荐楼主使用短连接。
    也就是说,发送端,发送完数据就自动断开连接,这样,接收端就可以回收资源。
    同样,这也要求,客户端可能也要监听某个端口,用于服务端向客户端传递信息。服务端同时处理多个连接,并且,每个连接的负载都不是很大的情况下,NIO是个不错的选择。
    一个线程可以监听多个连接,并且产生数据处理的事件,通过线程池技术,将事件进行处理。
    这种模式,对于楼主的应用场景应该是个不错的选择。至于服务器能够支持的最大连接数的问题,这个,其实,一般情况下楼主不用担心内存泄露的问题,
    而是,系统支持的最多连接数,根本达不到内存泄露的等级(当然,你别把JVM的内存调得那么小)。
    这个跟操作系统有关,我记得,Windows也就两千多个连接的样子吧。
    之后貌似抛出什么文件句柄无法分配的异常。至于IO流的问题,网络通信,TCP协议,操作系统内部会为每个应用程序建立IO数据缓冲区(或者说是滑动窗口)的,所以,无论是Java对象还是滑动窗口,都是消耗内存资源的。最后,我还是推荐短连接的方式发送消息。
    当然,如果楼主的应用场景,需要服务端将消息推送到客户端的话,
    并且,客户端这边存在NAT或者PAT的情况,可以考虑Socket重复绑定的设计思路。
    也就是说,向操作系统申请绑定一个端口,这个端口即可以作为监听端口,监听连入的连接,
    同时又可以以这个端口向服务端发起连接。这样,先用这个端口连接服务端,服务端就能获得客户端的IP
    和相应的端口号了,之后,如果服务端想向客户端发送消息,就用获得的IP和端口号发起连接请求即可。
    不过,这个对客户端的编程复杂度会加大很多,呵呵。
      

  7.   

    谢谢大神教导,受教了,其实我的这个应用用短连接是最好的。
    顺便问问,你们做java一般做什么啊?WEB吗?还是android?