I've just started exploring java NIO, non-blocking IO.
I'm interested to know the fundamentals behind the implementation. How is communication between Java selector and physical socket is established? Is there a operating system level thread that polls underlying resource continuously? And is there any java thread per selector continously polling to receive these events? Can someone of you kindly point me to this.
No, the point of select is that you don't have to waste cycles polling when nothing is happening. Every OS implements this capability in some way or other (usually through hardware interrupts) and makes it available to user-space programs through the select() system call. The connection to the Java language is that the JVM now contains code that will call the OS's select for you if you use the right NIO classes and methods. But this required changes to the JVM code itself, it isn't something that you could have done purely within Java before NIO.
Since it is not specified in the documentation, I'd assume that (strictly speaking) this is implementation dependent.
However in *NIX and Windows the implementation typically relies directly on the select system call. This system call is not implemented by spawning multiple threads.
It depends on the operation system used. On Linux the current implementation use's the kernel's epoll mechanism.
Typically the underlying kernel network system is filling or draining buffers for the socket, probably on it's IRQ handling threads. So what you are waiting for is the kernel to tell you that a buffer is ready to be filled (writing) or read to be draining (reading).
I think it's better first give you a picture(take from other guy's blog)
(source: csdn.net)
Also some information get from that blog,
For select implementation,it depends on OS. For epoll/select in *nix ENV, you can get more information from 《Unix network programming》
And for notify/wakeup the select, the JVM also use different implementation, like TCP/IP on windows, pipes on *nix.
Related
System.IO.File in .NET and .NET Core has a family of Read...Async() methods, all of which return either Task<byte[]> or Task<string> (Task<T> is the .NET's equivalent of Java's Future<T>).
This looks largely equivalent to AsynchronousFileChannel APIs (which either consume a CompletionHandler or return a Future), with one major difference.
AsynchronousFileChannel uses a managed background thread to perform asynchronous I/O (the thread may be provided either by the default thread pool (sun.nio.ch.ThreadPool) or by the ExecutorService explicitly specified during channel creation).
FileStream implementation in .NET, on the other hand, passes FileOptions.Asynchronous flag to the underlying operating system (see also Synchronous and Asynchronous I/O), doesn't spawn any managed background threads and uses what is called an Overlapped I/O.
Questions:
Is there any (existing or planned) File I/O API in Java which would use Overlapped I/O on Windows and POSIX AIO on Unices? Update: Windows-specific Java runtime features sun.nio.ch.WindowsAsynchronousFileChannelImpl which is exactly an abstraction layer on top of Overlapped I/O.
Are there any plans to provide java.nio.channels.SelectableChannel implementations for File I/O? If no, what are the technical limitations?
It is not really possible. The Whole IO API would have to be re-implemented. NIO means non blocking I/O it is not the same as Asynchronous I/O. Non blocking is implemented in JAVA and long story short that means the OS has no ability to notify runtime that operation is completed. Isned java uses select() or poll() system calls to check if data is available.
I could talk about it but stollen picture is worth 100 words:
That is why in JAVA the separate thread is required to constantly call check,check,check,check .....
I don't know .NET platform but if what you posted is correct it utilizing asynchronous I/O so the last column. But I don't trust anything that comes from Microsoft.
Hope it answers your question. Also here I a additional reading material:
https://stackoverflow.com/a/2625565/8951886
While working on a project using the the NIO.2 AIO features I looked in the "old" NIO selector implementation and saw that on windows the default select-function is used which does not scale at all on windows due to a bad internal implementation. Everybody knows that on windows IOCP is the only real solution. Of course the callback-on-completion model does not fit into the NIO selector model but does this effectively mean that using NIO on windows is basically not a good idea ?
For instance: The new AIO features include an IOCP implementation.
This is especially true while using the latest Netty framework where support for AIO has been dropped. So Netty is not as fast on Windows as it could be ?
NIO.2 uses IOCP
The call tree below demonstrates this for file i/o by featuring "Iocp" in several of the called class names, is from Java 7: NIO.2 File Channels on the test bench.
See also sun.nio.ch.Iocp.java, the "Windows implementation of AsynchronousChannelGroup encapsulating an I/O completion port".
NIO does not make use of IOCP, as it only supports "non-blocking i/o" (selectors), not "asynchronous i/o" (completion handlers) that was only added with NIO.2.
I think you are confusing asynchronous with faster. Certainly NIO buffers are faster than serializing the same data that would be in the buffers, but many AIO techniques incur costs and delays that can give synchronous IO an advantage.
There was an article a while back that did some pretty good benchmarking of various IO techniques, and the results were (a bit) surprising. The Netty people probably decided to align with the better performing (blocking) IO models mentioned.
The problem with IOCP and Java is that IOCP creates and manages threads. My understanding is that for IOCP to work in Java, the event system actually has to go through the Windows IOCP Thread, then scheduled on the Java ThreadPool for execution. This makes IOCP very very expensive to implement in Java versus C++/C#.
AIO was probably removed from Netty because no one wants to sacrifice 450,000 potential transactions just to use AIO versus NBIO. The transactional performance gap between AIO and NBIO is huge.
I would like a solution that doesn't include critical sections or similar synchronization alternatives. I'm looking for something similar the equivalent of Fiber (user level threads) from Windows.
The OS manages what threads are processed on what core. You will need to assign the threads to a single core in the OS.
For instance. On windows, open task manager, go to the processes tab and right click on the java processes... then assign them to a specific core.
That is the best you are going to get.
To my knowledge there is no way you can achieve that.
Simply because the OS manages running threads and distributes resources according to it's scheduler.
Edit:
Since your goal is to have a "spare" core to run other processes on I'd suggest you use a thread manager and get the number of cores on the system (x) and then spawn at most x-1 threads on the specific system. That way you'll have your spare core.
The former statements still apply, you cannot specify which cores to run threads on unless you in the OS specify it. But from java, no.
Short of assigning the entire JVM to a single core, I'm not sure how you'd be able to do this. In Linux, you can use taskset:
http://www.cyberciti.biz/tips/setting-processor-affinity-certain-task-or-process.html
I suppose you could run your JVM within a virtualized environment (e.g., VirtualBox/VMWare instance) with one processor allocated, but I'm not sure that that gets you what you want.
I read this as asking if a Java application can control the thread affinity itself. Java does not provide any way to control this. It is treated as the business of the host operating system.
If anything can do it, the OS can, and they typically can, though the tools you use for thread pinning will be OS specific. (But if the OS is itself is virtualized, there are two levels of pinning. I don't know if that is going to work / be practical.)
There don't appear to be any relevant Hotspot JVM thread tuning options in modern JVMs.
If you were using a Rockit JVM you could choose between "native threads" (where there is a 1-1 mapping between Java and OS threads) and "thin threads" where multiple Java threads are multiplexed onto a small number of OS threads. But AFAIK, JRocket "thin threads" are only supported in 32bit mode, and they don't allow you to tune the number of OS threads used.
This is really the kind of question that you should be asking under a Sun support contract. They have people who have spent years figuring out how to get the best performance out of big Java apps.
Using java IO, it seems like forking a new process gives better ability for a process B to read data written by process A to file than what you could get if thread A wrote to a file that thread B is trying to read (within the same process).
It seems like the rules are not comparable to the memory model. So what file-based concurrency works ? References would be appreciated.
Any observations like this bound to be operating system specific, and may be specific to different versions of the operating system (kernel). What you are hitting here is probably related to the way that the OS implements threads, and thread scheduling. The Java platform provides little in the way of tuning for this kind of thing.
IMO, if you need better performance, you probably should not be using a file as a data transfer channel between two threads in the same JVM. Code your application to detect that the threads are colocated in the same JVM and use (say) Java Pipe streams.
Maybe it could have to do with thread and process blocking.
When a process wants a resource (writing/reading a file) it blocks untils the S.O. fulfills the requirement and return something to the process.
If you are not using hyperthreading a process with two threads will block both threads for fullfilling each one of the tasks. But if you separate them, maybe the S.O. can optimize access and paralelize the read/write better.
(just guessing :)
Is there a reliable, cross-platform way to do IPC (between two JVMs running on the same host) in Java (J2SE) that doesn't rely on the network stack?
To be more specific, I have a server application that I'd like to provide a small "monitoring" GUI app for. The monitor app would simply talk to the server process and display simple status information. The server app has a web interface for most of its interaction, but sometimes things go wrong (port conflict, user forgot password) that require a local control app.
In the past I've done this by having the server listen on 127.0.01 on a specific port and the client communicates that way. However, this isn't as reliable as I'd like. Certain things can make this not work (Windows's network stack can be bizarre with VPN adapters, MediaSense, laptops lid closing/power saving modes). You can imagine the user's confusion when the tool they use to diagnose the server doesn't even think the server is running.
Named Pipes seem plausible, but Java doesn't seem to have an API for them unless I'm mistaken. Ideas? Third party libraries that support this? My performance requirements are obviously extremely lax in case that helps.
One of my specialties is really low-tech solutions. Especially if your performance requirements aren't critical:
The low-low tech alternative to named pipes is named FILES. Think yourself up a protocol where one app writes a file and another reads it. If need be, you can do semaphoring between them.
Remember that a rename is pretty much an atomic operation, so you could calmly write a file in some process and then make it magically appear in its entirety by renaming/moving it from somewhere that wasn't previously visible.
You can poll for data by checking for appearance of a file (in a loop with a SLEEP in it), and you can signal completion by deleting the file.
An added benefit is that you can debug your app using the DIR command :)
Depending on how much data you need to pass between the server and the diagnostic tool you could:
go low-tech and have a background thread check a file in the file system; fetch commands from it; write ouput into a second to be picked up by the diagnostic tool.
build a component that manages an input/output queue in shared memory connecting to it via JNI.
Consider JMX. I do not know if any of the Windows JVM's allow JMX over shared memory.
Does Windows even have named pipes? I was going to suggest it. You'd just have to use an exec() to create it.
Map a read_write byte buffer into memory from a FileChannel. Write status information into the byte buffer, then call force() to get it written out. On the monitor side, open up the same file and map it into memory too. Poll it periodically to find out the status.