I have a JavaFX 8 app that is occasionally hanging/freezing. I feel I've ruled out many causes of the problem, but it's still happening.
Unfortunately I cannot reproduce the freeze/hang on demand. It actually only happens (so far) on my colleague's computer. It can happen not long after the App has been running, or it may happen after many hours, or it may not happen at all. It does not happen after any user initiated event (such as pressing a button).
I have a few background threads running that read data from sockets and update the JavaFX UI. These updates are always done via the Platform.runLater() method.
The background threads may read many hundreds of data updates per second, so I have applied throttling to prevent too many updates on the UI, as suggested here: Throttling javafx gui updates
The user can initiate some long(ish) tasks, which are run on the JavaFX UI thread, or using the Task method. I know and expect the JavaFX UI to block/freeze when calling a method with long execution time on the JavaFX UI thread. But such calls are only made by the user pressing a button and as stated above, the freeze occurs without the user interacting the the App in any way.
I have caught the freezing (twice) on my colleagues computer and inspected the process in JConsole and VisualVM. The thread dump showed no deadlocks. When I compare the thread dump with a non-frozen JavaFX App thread dump, there are no obvious differences.
It appears that only the JavaFX UI is frozen. The background threads continue without error.
The CPU is not high and the computer is not running slow when the freeze occurs.
My App code consists of many classes, so it's not straight forward to include it here, especially as I don't know which method causes to freeze. And therefore my question is rather broader than I would like:
Given the assertions above, do you have any suggestions as to what
might be a cause of such an error?
Given the assertions above, do
you have any suggestions as to what might be another way to trace
such an error?
Thanks to John16384 and Mipa for their replies...
I use the javafx-maven-plugin Maven plugin, so the JavaVM arguments by including:
<jvmArgs>
<jvmArg>-Dprism.verbose=true</jvmArg>
<jvmArg>-Dprism.order=sw</jvmArg>
</jvmArgs>
in my plugin configuration. Since including this, we haven't had the freeze for a couple of days. I'm hoping this is the final fix!
Have you tried AOP ?
Aspect Orientated programming
It in your case would allow you to run a method before and after every method you use, if you logged something if these times were greater than a certain time, then you could determine which bit of code was causing it e.g. log if the time inside a method is greater than 5 seconds
See here for a tutorial to just that
Related
I want to prevent the thread from stopping during the transition between activities and call this thread during the start of my application. I have one option and I would like to share it. So far, I have stopped at writing an android service in which to include the beginning of the stream that, I need to perform. And then call it in the class inherited from the application class. It is important to note that my thread will send certain data to the database every minute. Perhaps you can advise a more reliable and popular way to solve the problem.
Threads don't stop between Activities. That would be impossible to do safely- threads cannot in general be safely stopped by anyone but the thread itself without risk of data corruption or deadlock. So Android doesn't even try. (You can cancel a thread from another thread, but that works by setting a flag and hoping that the thread you want to cancel looks at it occasionally to honor it.)
The real problem is twofold
1)How do you know if the thread is already running so you don't launch it again. This is solvable in a variety of way.
2)Do you want the thread to work when the app is in the background? This is the real problem, because Android kills background apps regularly, which will end the thread. There is no reliable way to make a thread run constantly in the background in Android. Here your best bets are either a foreground service running to keep the app active, or to not use a thread and make your app even t driven (for example, setting a repeating alarm for every 15 minutes and running then).
I'm currently attempting to debug a medium scale (in the 10's of thousands of lines ballpark) Java project which uses both JavaFX and Swing, and I'm hitting some odd exceptions every so often which I'm pretty sure are because of UI code not being called on the correct thread. The stack trace for these exceptions isn't really helpful at all, since they pretty much all originate from the UI drawing thread.
Now, sure I could sit down with a toothcomb and debug every UI call until I find one that's not being called on the correct thread, and keep doing that for the entire project, but that would be an incredibly long task. Is there some form of easier way to do this sort of debugging? For instance, somehow cause UI code to print out a debug message or throw an exception when it's not been called from its appropriate thread?
Running JavaFX and Swing on the same thread might help fix your threading issues.
There is an experimental feature in Java 8 to run JavaFX and Swing on the same thread:
https://javafx-jira.kenai.com/browse/RT-30694
http://bugs.sun.com/view_bug.do?bug_id=8015477
I think -Djavafx.embed.singleThread=true is the command line property setting to enable the experimental single threading system.
I am not sure if the experimental feature is available in the current Java 8 builds, but I think it might be now, so you may wish to try it.
If you need more information on the experimental single threading feature, you could ask the developers on the openjfx-dev mailing list.
Java 8 has better inbuilt reporting of when code is not run on the correct thread, it's not comprehensive, but it might assist you in locating the source of your error, even if you are not using the single threading option.
Some other users running large applications merging Swing and JavaFX reported similar hard to debug threading issues, so you could check those threads to see if your issues have the same cause.
You could turn on thread checks in glass by -Dglass.disableThreadChecks=false. This would switch on the thread checks in the lowest layer of JavaFX which is responsible for working with OS level APIs. In most cases those checks would be sufficient, because most of the calls are ending up in Glass. These checks would be enabled by default soon.
I recently ported a fairly large application from C# to Java. It ought to have about 6 main threads running and lots of timers being fired (but each executing only briefly). I make use of the Timer class and call myTimer.schedule(new TimerTask() { ...
Now that I'm at the end of the port, I'm having a problem debugging the application in Eclipse, especially lately. I set a breakpoint: Eclipse will hit it but I can't step through at that point. I don't think I can look at variable values or stack trace or anything.
I see my list of threads going crazy, and based on output statements I've written, I can see that Thread.activeCount() gets to be over 200 threads. I am curious as to whether this is my debugging problem. Have I overloaded Eclipse to the point that it goes crazy?
From the threads I can actually see, most of them are my Timers that have been run. Somewhere I read that the JVM will keep those alive even if you cancel them (?). Anyway, if it's including all of the timers I've fired then perhaps over 200 threads makes sense.
I did once today also see an Eclipse "out of memory" error.
Any advice? Thanks.
I have a Swing GUI running on WinXP.
Sometimes, when i do something else (surf on the web...) and then i want to go back to my program, the GUI appears but is totally frozen, i can't do anything on it.
I have to wait (it can be 10sec or 5min) untill it works again.
I noticed the same problem when i come back from the screensaver (so I disabled it).
The machine isn't in cause, RAM and processor levels are ok.
Do you have any idea of the source of this very annoying problem? Maybe a repaint problem?
There might be many explanations to that:
Your app does some heavy operations in EDT thread (thread that controls interface updates)
There might be a UI update problems caused by errors in L&F or components (a rare case)
GC happens due to some internal call and handles the whole application (less likely)
Some native or old JDK problems with app windows (almost 0% chance that it is your case)
Usually the 1st explanation works and in that case you should just review your code and extract all "heavy" operations in a separate threads.
Anyways, i can't say anything more specific without seeing the code...
I'm developing an artificial intelligent program to explore a given space for resources.
I'd like to run multiple scenarios in order to collect data and output to a file.
I used the "multiple runs" option in the gui and i do stop() when one module run is finished (all the resources have been explored). The problem is when It runs the model a second turn, it doesn't work properly.
What I mean is that after running once I always need to kill the application by exiting because the restart option doesn't work properly.
Is there anything that "restart" forgets to do? Because if I exit the application and run it again it works perfectly
Edited so it's more clear:
I use the Repast platform in order to simulate an exploration to Mars. I have 3 kinds of agents, scouting, digging and transporting. They communicate among them to schedule tasks and other things.
The first time I run the simulation everything runs smoothly. And when all the mineral resources of the planet have been explored I restart the model and try again so I can collect data.
The problem is, when I use the "restart" option the Simulation doesn't run well. But if I exit (not restart) and run it again it works fine.
What I'd like to know is if the restart option of Repast GUI misses any steps..
Thanks in advance
PS: If you guys think that it's absolutely necessary I can post some code...but the project is quite big
Don't use Thread.stop() method. It is deprecated. Thread.stop is being deprecated because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors was in an inconsistent state, other threads might view these objects in an inconsistent state. Such objects are said to be damaged. Threads operating on damaged objects can behave arbitrarily, either obviously or not. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that the program may be corrupted. The corruption can manifest itself at an unpredictable time after the damage occurs. Substitute any use of Thread.stop with code that provides for a gentler termination.
http://docs.sun.com/app/docs/doc/805-4031/6j3qv1of1?a=view
Consider thread stopping either via Thread.interrupt() or via setting cancel flag. Look at Java Concurrency in Practice, Section 7.1. Task Cancellation.