Posted by claudio
on May 23, 2007 at 9:14 PM PDT
I developed a performance utility to test the scalability of threads per java process. Test it and see how many threads you system can afford to create and run concurrently.
A customer asked me to verify how many threads is possible to run concurrently at any java vm on the server. I did some search at the customer support site , but was not lucky to found any proper test utility, so I created one and hope it be useful to someone else.
At first I thought it was just a matter of a for loop, create and start the thread inside the loop. Easy task.
As I ran the test with 1k, 10k threads I saw that many threads finished before others were even created, so I needed to first create all thread object, without starting it. Wow, that is not easy to create such a mechanism, but for my lucky there is the concurrent library from Doug Lea , from there I use the CyclicBarrier class.
As that was not enough, the processing task needed to be intensive, then some Random class were created and math operations at them.
The utility class can be run from command line and deployed as war application. It is compatible to run under JDK 1.4 and Java EE 1.3.
As JDK 1.4 is a required platform, I could not use Java Concurrent API, but used the util.concurrent from Doug Lea.
Take a look at the readme.txt file, there are some useful information there.
Download and test the thread capacity application .
Update (2007/05/24): The source code
This utility test the ability to create many threads as possible per java process,
as the user request it by command line or http parameter.
This test can be run from command line or deployed as an war file.
The reason to test it from a servlet container is to see the thread limit per
appserver instance, as each instance have different JVM tuning from command line.
Beware that the maximum number of threads can be different when running from
command line and servlet container.
* There are some JVM parameters that cannot be tuned as the command line,
such as -Xmx and -Xss
* At servlet container there are thread pools and thread management
JDK 1.4, 1.5 and 6
Java EE 1.3 and 1.4
package util.concurrent (Doug Lea)
By default the application will use the system default. If you want to specify different locale
use the environment variable (unix) LANG before invoking the script, example:
At the AppServer, use the java properties -Duser.language and -Duser.country
First, all thread objects is created (new Thread)
A CyclicBarrier is used to control the exact moment, when all thread objects are
ready to run.
All threads are started, but its run method has a barrier to wait until all
threads have its method start() invoked.
The reasoning is to have all threads to run concurrently.
After all threads are properly running, there is a join() call on each thread, to
make the main method wait, until all threads run sucessfully or are interrupted
by some error.
As this is a test of resource usage, be careful because the system can be
unresponsive at all.
The war file has authentication disabled, to enable it, edit web.xml and uncomment
the security section.
Its possible to run this test on public accessible machine, for this to work,
create any user at the file-realm and associate it with the group named "threadtest"
To use this thread test, you can invoke the start_thread_test.sh script.
First, you need to unpack the war file. I recommend to create a new directory
and unpack it there.
jar xf ../thread-capacity-web.war
chmod +x *.sh
./start_thread_test.sh [n] [thread repeat]
[n] is the desired number of threads (default = 15000)
[thread repeat] the number of interactions inside the thread (default = 100)
The number of threads can be monitored through operating system tools, such as:
* Linux: ps -p PID -o pid,user,%cpu,rss,etime,nlwp,args
The NLWP column display the number of threads
* Solaris: prstat -c -p PID 1 100
At the root of war file there are some better shell scripts to monitor and run
./linux_threads_per_process.sh updatecenter 300
threads_per_process.sh PID | process name [count] "
PID: 36434 OR
process string: NumThreads (this script will do a ps -ef|grep NumThreads to get the PID)
The last number is the number of times the command will run
threads_per_process.sh 36434 20"
threads_per_process.sh 36434 "
threads_per_process.sh NumThreads 20"