Build: NetBeans IDE 8.0.2 (Build 201411181905)
VM: Java HotSpot(TM) Client VM, 25.40-b25, Java(TM) SE Runtime Environment, 1.8.0_40-b26
OS: Windows 7
daniele.rinaldelli: again and again...executing junit test
java.lang.OutOfMemoryError: unable to create new native thread
Created attachment 157138 [details]
It looks like this problem is caused by Gradle Support. It would be great if you can provide steps how to reproduce it.
Attila, can you please take a look at this issue? Thanks!
(In reply to Tomas Hurka from comment #2)
> It looks like this problem is caused by Gradle Support. It would be great if
> you can provide steps how to reproduce it.
Unfortunately I can't give you any hint about how reproduce it because it can happen never or several times on a working day.
The only thing I can be rather sure is that it depends on gradle and in particular when running the test suite (I run tests several times per day).
This info is not enough for me even to decide if it is Gradle related or not. Something eats up the memory. It would be best to see a memory dump in order to see what objects are being retained.
(In reply to daniele.rinaldelli from comment #6)
> dump file
What should I download from here? Can you give me a direct link to your heap dump? Also, some info about the NetBeans process: Number of threads, memory in use.
Danielle, can I share your heap dump with Attila? I would tranfer the file to a publicly available place if you agree.
Yes Jiri of course you can, thank you.
(In reply to attila.kelemen from comment #5)
> This info is not enough for me even to decide if it is Gradle related or
> not. Something eats up the memory.
Even though this is reported as OutOfMemoryError, the issue here is "unable to create new native thread". So something is creating too many threads - there is no memory problem.
> It would be best to see a memory dump in
> order to see what objects are being retained.
Heap dump is useful, but you need to look for threads and why so many are running.
Great, thanks. The heap dump is here: https://netbeans.org/projects/qa/downloads/download/heapdump_256355.zip
(In reply to Tomas Hurka from comment #10)
> Even though this is reported as OutOfMemoryError, the issue here is "unable
> to create new native thread". So something is creating too many threads -
> there is no memory problem.
It is not necessarily so. Failing to create thread could easily be the cause of low memory (especially since it needs a stack). Anyway, I'll check the memory dump.
I did a quick look at the dump and the number of threads is definitely unhealthy: 66 (although, this is not extreme enough to completely explain the situation). Still, there shouldn't be this many input reader thread (started by the Gradle API) living. Looking at the source code of Gradle, my suspicion is that the input streams of the output window prevent Gradle's input reader thread to terminate (since their read method won't return).
I might find some time to have a look at this issue in the weekend (can't promise). Until then, try closing the output windows (or even press ctrl+D in them) and see if it helps (i.e., it would be nice to know if it helps).
Ok I'll try with output windows closed and verify whether it helps.
Could be necessary a few days to have some hints due the issue doesn't happen regularly.
Thanks in advance
I looked at this issue a little more and it is worse than I thought. Here is what happens exactly:
1. User starts a new Gradle command.
2. A new output window is created (or an old one is reused).
3. The plugin will set the InputStream (or Reader) of the tab for Gradle to use. (possibly wrapping the InputStream).
4. Gradle will start a new thread to poll the InputStream to forward the input to the Gradle daemon (notice that this is the only thing Gradle can do with an InputStream).
However, since the InputStream does not get closed, Gradle's polling thread will wait forever for `read` to return. The only thing to prevent this is to press "Ctrl+D" (i.e., manually close the stream). Not even closing the output window will help. So, as a result you will have as many stuck threads as many different output window you had since opening NetBeans (minus the ones whose input was closed explicitly).
Currently, the only thing I can do on the plugin's side is to allow the user to enable/disable the input stream in the settings (global/project).
In my opinion, the best solution would be if both Gradle and NetBeans allowed for asynchronous input receiving/providing. Though, even if only NetBeans had this feature, I could create a reasonable fix. (If only Gradle had it, that would be useless in itself).
As a second best solution: NetBeans could let me replace the InputStream of a tab and close the old InputStream. Say, InputOutput had a method like "createNewInput()". Please, correct me if I'm wrong and NetBeans already has this feature.
@Daniele Would it be a reasonable workaround for you if I let you disable the input in the output tab? (I believe the majority of projects don't use stdin anyway).
Looking at the sources of NetBeans and Gradle, I think I have found an ugly workaround. Since Reader.ready is properly implemented in NetBeans, I can poll read in a loop with a sensible timeout and the Gradle code seems to work properly even if InputStream.read returns 0 bytes and does not use the single byte read method.
I will implement this workaround tomorrow. Regardless, it would be nice to have a proper solution.
From my side, trying to develop with output windows closed have not eliminated the issue.
I have just tried to limit the number of gradle projects opened in netbeans in order to limit the problem frequency.
I guess that Netbean 8.1 suffer of the same matter, doesn't it?
Hope there will be found a proper solution to close the bug.
As I wrote before, I have tried myself and closing the output windows have no effect. You have to press Ctrl+D in the window for the threads to die. Also, there could be other problems like too many Gradle daemons or something else using too much memory.
I have found a better solution: NetBeans already lets me "replace" the input stream (which I said to be the second best solution). I just have to close its Reader explicitly. So this is a reasonably good solution. Still, it would be nice to have an asynchronous API to receive input (it would be more efficient) :)
@Daniele May I ask you to build the plugin (https://github.com/kelemen/netbeans-gradle-project) from the sources and verify if it works for you (for 8.1 use the NetBeans81 branch for 8.0x use the master). It should build out of the box but if you have any trouble refer to the wiki: https://github.com/kelemen/netbeans-gradle-project/wiki/Development or just email me. Thanks.