JDK-4503092 : (so) Selector only supports 63 channels (win)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 1.4.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_nt,windows_2000
  • CPU: x86
  • Submitted: 2001-09-14
  • Updated: 2002-05-28
  • Resolved: 2002-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.1 hopperFixed
Related Reports
Duplicate :  
Description

Name: nt126004			Date: 09/14/2001


java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)

I am using the new java.nio.channels package to write a server application
that needs to support thousands of concurrent users. These are not short
running HTTP requests, but rather long running sessions. The way to go is to
use non-blocking IO. After spending some time figuring out how to use the
package I tried running some stress tests. Everything was fine until I hit
it with more then 62 users, when I did I got the following error:

java.lang.UnsupportedOperationException: Implementation allows only 63 channels
per Selector
        at sun.nio.ch.PollArrayWrapper.addEntry(PollArrayWrapper.java:123)
        at sun.nio.ch.PollSelectorImpl.implRegister(PollSelectorImpl.java:144)
        at sun.nio.ch.SelectorImpl.register(SelectorImpl.java:112)
        at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSele
ctableChannel.java:166)
        at NBTest.startServer(NBTest.java:85)
        at NBTest.main(NBTest.java:111)

63 Channels per selector is utterly useless if you want to write a scalable
server application, the reason for java.nio.channels to exist in the first
place.

I have run the same test on Solaris and on Linux and the problem did not occur
there, although I did need to increase the number of file handles the system
allows for Redhat Linux 7.1

Code to reproduce the problem:

/*
 * NBTest.java
 *
 * Created on 01 September 2001, 21:20
 */

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;

/**
 *
 * @author  Administrator
 * @version
 */
public class NBTest {


    /** Creates new NBTest */
    public NBTest()
    {
    }

    
    private static void debug(String s)
    {
        System.out.println(s);
    }
    
    
    private static void printKeyInfo(SelectionKey sk)
    {
        String s = new String();
        
        s  = "Att: " + (sk.attachment() == null ? "no" : "yes");
        s += ", Read: " + sk.isReadable();
        s += ", Acpt: " + sk.isAcceptable();
        s += ", Cnct: " + sk.isConnectable();
        s += ", Wrt: " + sk.isWritable();
        s += ", Valid: " + sk.isValid();
        s += ", Ops: " + sk.interestOps();
        debug(s);
    }
    
    
    public void startServer() throws Exception
    {
	int		    channels	= 0;
	int		    nKeys	= 0;
        int		    currentSelector = 0;
	Selector	    selector    = Selector.open();
        ServerSocketChannel ssc		= ServerSocketChannel.open();
        InetSocketAddress   address	= new InetSocketAddress
(InetAddress.getLocalHost(),9000);

        ssc.socket().bind(address);
        ssc.configureBlocking(false);
        
        SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);
        printKeyInfo(s);

        while(true)
        {
	    debug("NBTest: Starting select");
            nKeys = selector.select();
            if(nKeys > 0)
            {
                debug("NBTest: Number of keys after select operation: " +
nKeys);
                Set selectedKeys = selector.selectedKeys();
                Iterator i = selectedKeys.iterator();
                while(i.hasNext())
                {
                    s = (SelectionKey) i.next();
                    printKeyInfo(s);
                    debug("NBTest: Nr Keys in selector: " + selector.keys().size
());
                    i.remove();
                    if(s.isAcceptable())
                    {
                        // Get the SocketChannel
                        Socket socket = ((ServerSocketChannel) s.channel
()).accept();
                        SocketChannel sc = socket.getChannel();
                        sc.configureBlocking(false);
                        sc.register(selector, SelectionKey.OP_READ |
SelectionKey.OP_WRITE);
                        System.out.println(++channels);
		    }
                    else
                    {
                        debug("NBTest: Channel not acceptable");
                    }
                }
            }
            else
            {
                debug("NBTest: Select finished without any keys.");
            }

        }
    }
    
    
    /**
    * @param args the command line arguments
    */
    public static void main (String args[])
    {
	NBTest nbTest = new NBTest();
        try
        {
            nbTest.startServer();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

}

Run this application and telnet to port 9000. It doesn't do much, it just
accepts incoming connections and adds those to the selector.
(Review ID: 131555) 
======================================================================

Name: nt126004			Date: 09/14/2001


java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)


The problem is simple, if we try to register more than 63 SocketChannel on one
Selector we get :

java.lang.UnsupportedOperationException: Implementation allows only 63 channels
per Selector
        at sun.nio.ch.PollArrayWrapper.addEntry(PollArrayWrapper.java:123)
        at sun.nio.ch.PollSelectorImpl.implRegister(PollSelectorImpl.java:144)
        at sun.nio.ch.SelectorImpl.register(SelectorImpl.java:112)
        at java.nio.channels.spi.AbstractSelectableChannel.register
(AbstractSelectableChannel.java:166)

For a server more than 63 concurrent sessions is far to be exceptional.

I can see 3 possible origins to this limitation :

1) This limitation is due to the way the implementation of the Selector (or one
of its dependencies) has been done. --> implementation should be extended

2) This limitation has been artificially added because of a performance
degradation due to some native bottleneck on the selection of the socket -->
should eventually let us the choice to go above this limit

3) This is a limitation of the native calls to select a socket --> not much one
can do about it, but it should be documented somewhere.
(Review ID: 131887)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: hopper FIXED IN: hopper INTEGRATED IN: hopper VERIFIED IN: hopper-beta
14-06-2004

WORK AROUND Name: nt126004 Date: 09/14/2001 Customer Workaround: Create a pool of threads, each hosting its own selector. ALternatively don't use more then 63 channels while developing your application. I am sure Sun will remove this limitation before they release the final version of 1.4 ====================================================================== Name: nt126004 Date: 09/14/2001 Customer Workaround: We have to use several Selector. The problem there is that its not possible to register a new channel for a selector if the selector is blocked on a select(). Since the wakeup() method is currently not working on NT (reported bug 4467968), some not so nice alternatives could be used: - use select(long timeout) - interrupt the thread... - act on a dedicated registered Socket to encourage the select to wake up (Review ID: 131887) ======================================================================
11-06-2004

PUBLIC COMMENTS Now we have a new Selector implementation for Windows, which can support thousands of channels.
10-06-2004

EVALUATION This is a known problem that only affects Windows platforms, and is due to the fact that WaitForMultipleObjects can only handle 64 events at a time. A fix is in progress and is slated for the 1.4.1 release. -- ###@###.### 2002/3/22
03-10-0188