aspose file tools*
The moose likes Threads and Synchronization and the fly likes Unable to create native thread in Normal Condition Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Unable to create native thread in Normal Condition" Watch "Unable to create native thread in Normal Condition" New topic
Author

Unable to create native thread in Normal Condition

veerabahu Subramanian
Greenhorn

Joined: Jun 01, 2007
Posts: 17
I am trying to analyze the "OOM unable to create native thread" error that occurred in our application. I wrote a sample program which has to creates 5000 threads and monitored it using JConsole.

I started the program using the following command line option..

"c:\Program Files\Java\jdk1.5.0_09\bin\java.exe" -Dcom.sun.management.jmxremote.port=9979 -Xmx512m -Xminf0.1 -Xmaxf0.1 -XX:MaxPermSize=256m -XX ermSize=256m -XX:+<GCTYPE> -XX:+PrintGCDetails

where GCType will be UseTrainGC or UseSerialGC or UseParallelGC or

What i observe in all the cases, there are no more than 1000 threads getting created . After completion of 1000 threads garbage collector keeps running and no more threads get created. Since i have configured heapsize to be 512m, PermGenSpace to be 256 and default value for process sapece is 2gb, JVM would be able to create only 1000 threads as per the formula "NoOfThreads = Process space - (Heap + permGen+some for VM initialization)/Stack Size" (correct me if i am wrong). But why i am not getting OutOfMemoryError while creating native thread. Moreover i can observer non-heap (Perm Gen) space keep growing overtime. But there is enough space in all other spaces.So my doubts are
1. Actually when we will get OOM error saying unable to create Native thread. To be more specific when which space occupied i will get this error.
2. Is there any way to configure process space. IMO No ?? Confirm ??
3. Does any one tried using a a tool that analyzes verboseGC output of SUN JVM. If so can you give any pointer. I have read through GCPortal, but i havent fully deployed it.

Java version is 1.5.0
OS Windows 2k3

Snippet of GC Output


[GC [DefNew: 5208K->38K(5824K), 0.0072564 secs] 32049K->26879K(34636K), 0.0080451 secs]
[GC [DefNew: 5222K->24K(5824K), 0.0070320 secs] 32063K->26868K(34636K), 0.0078097 secs]
[GC [DefNew: 5208K->39K(5824K), 0.0082161 secs] 32052K->26883K(34636K), 0.0090173 secs]
[GC [DefNew: 5223K->27K(5824K), 0.0080766 secs] 32067K->26874K(34636K), 0.0089273 secs]
[GC [DefNew: 5211K->39K(5824K), 0.0071186 secs] 32058K->26886K(34636K), 0.0078970 secs]
[GC [DefNew: 5223K->25K(5824K), 0.0070952 secs] 32070K->26875K(34636K), 0.0078766 secs]
[GC [DefNew: 5209K->21K(5824K), 0.0069871 secs] 32059K->26872K(34636K), 0.0077657 secs]

[ added code tags - Jim ]
[ June 01, 2007: Message edited by: Jim Yingst ]
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

When you post code use the code tags and format the code and leave out the extraneous comments (@author Administrator just gets in the way.)

Your variable BufferedReader in = null; is not protected from concurrent modification by multiple threads and the result is unpredictable.

The method public void waitTillEnter(){ is called before starting a thread and depends on the unprotected variable "in".

Other then that, I have no idea what you are trying to do.


Ed's latest article: A Java Parallel Calamity http://coopsoft.com/ar/Calamity2Article.html
veerabahu Subramanian
Greenhorn

Joined: Jun 01, 2007
Posts: 17
Thanks for your time.

Sorry i was not aware of tips that you gave me now. Sure will take care going forward. The main aim of bufferedreader is to make the thread wait for some input from user, so that it wont exit. Actually there is no modification done to that
which is specific to a thread instance. The logic of the sample code is as follows, once the JVM is started the program will wait for some user input (added this so that i can attach the JConsole) once the user input is given 1000 threads will be created in a shot. After this it will again wait for some user input (this gap i have given so that Jconsole can update itself with the new values). The above logic should run for 4 more times. but actually it runs only once (i.e. only 1000 threads created).
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

Looking at wrong code is like looking at a misspelled word. It's hard to spot the error. This is why formatting the code you post is important. Use the buttons under "Instant UBB Code" when posting.

Since the variable "in" can be modified by many threads and because of concurrency issues, the value of "in" at anytime is unpredictable. There isn't enough space to go into concurrency issues here. You need to use synchronized or another form of locking to avoid problems.

Rather than dummy.waitTillEnter();, use Thread.sleep(5000) in a try/catch block. This pauses the execution. Get rid of the BufferedReader.

You create a new thread, but never call start(). The thread never executes.
You loop creating 1,000 threads.
Then you have this wait on the buffered reader. Use sleep().
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Edward Harned:

Since the variable "in" can be modified by many threads and because of concurrency issues, the value of "in" at anytime is unpredictable.


Sorry, but there are no concurrency issues regarding the variable "in" itself. Each instance of the Thread subclass has its own copy of "in", as it's an instance variable.

Now, the fact that many BufferedReaders are connected to the same InputStream, that can be a problem; and the fact that he's using BufferedReaders in System.in is another problem. If you ever have to do this, supply a second argument (the number 1) to the BufferedReader constructor; this turns off buffering. If you don't do this, you can get some weird effects.


Rather than dummy.waitTillEnter();, use Thread.sleep(5000) in a try/catch block. This pauses the execution. Get rid of the BufferedReader.


It pauses the execution until the user presses a key. What you're proposing is rather different, of course.

You create a new thread, but never call start(). The thread never executes.


Yes, he sure does. Now, I'm unclear on why run() calls readLine() -- I don't think he wants to press Enter 5000 times! Perhaps run should call Thread.sleep(100000), and save the readLine() for every thousandth thread.

So that's why you're seeing only the fixed number of threads: when you get to a thousand, no more are created because the main loop is waiting for Enter; but any of the thousand other threads is likely to steal that Enter. You need to press Enter 1000 times (thus terminating all 1000 of the threads) before the main loop will proceed to create any more!


[Jess in Action][AskingGoodQuestions]
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

Yes, "in" is an instance variable. I missed that. Hard to see with all the extraneous lines.
veerabahu Subramanian
Greenhorn

Joined: Jun 01, 2007
Posts: 17
How BufferedReaders are connectoed to same input stream, they are also created each time rite?. Yes i might get some wierd output if am not turning off the bufferer, but since i use this for test i careless for putting the same.
Thanks for pointing out the issue in the code. I am now able to get more threads after pressing enter 1000 times. But still my base question are not get resolved

1. Actually when we will get OOM error saying unable to create Native thread. To be more specific when which space occupied i will get this error.
2. Is there any way to configure process space. IMO No ?? Confirm ??
3. Does any one tried using a a tool that analyzes verboseGC output of SUN JVM. If so can you give any pointer. I have read through GCPortal, but i havent fully deployed it.

Actually i started with a test program to reproduce the issue but ended up in writing a wrong code. So can you give pointers for those things.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

1) When you press Enter, and one of your threads reads it, the thread then terminates. This program can't create more than 1000 threads without disposing some. Change your readLine() to a sleep(), as suggested, or something like

synchronized("Dummy") { "Dummy".wait() }

and you'll then be able to create too many threads. I think on Windows the limit is around 2000.

2) Since JVMs these days virtually always just use the OS's native thread library, this is obviously an OS-specific issue, nothing to do with Java. Refer to your OS documentation.

3) There are lots of commercial memory-analyzer tools. There was, at one time, a free tool called "HAT" (Heap Analysis Tool, I think) that may do what you want. Google is your friend here.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Unable to create native thread in Normal Condition