Java Swing GUI frozen on refocus - java

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...

Related

How To Trace A Tricky JavaFx Freeze / Hang

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

Memory build up in a java program GapContent$MarkData

I am currently developing an application that need to be very fast executing about every 20ms (yeah I know, should not have taken Java in the first place). I worked a lot optimizing the code so it would not be too computation greedy. However, as I have seen I may have not put enough effort in GUI and memory optimization. My application can run at the speed I want but after 1-2 minutes it drastically slowdown suggesting a memory problem.
I did run the profiler under NetBeans and found out that most of the memory was taken by the javax.swing.text.GapContent$MarkData
And searched on google, I saw mostly nothing understandable helping me with that problem. So is there anyone that could help me? My first guess would be that the garbage collector doesn't run long enough to erase unused object...but I don't have more clue than that.
You are right to employ profiling; now use Profile > Profile Project > CPU to find and target the hot spot(s).
The slowdown was due to a function that closed and opened a connection with the database each iteration.
Consider using SwingWorker to query the database in the background and process() results on the event dispatch thread, as shown in this related example.
What you are calling a "Memory build up" is only 600Kb. If this 600Kb is problematic I question your choice of Java and Swing.
I have an application that sometimes generates hundreds of megabytes of log messages.
I'm guessing your GUI application is somewhat similar. The app probably has a JTextPane that displays a log. As the app runs it adds messages to the JTextPane.
The Document implementation used by JTextPane is a PlainDocument.
Even though you probably always insert new log messages at either only the top or only the bottom, the PlainDocument implementation is general-purpose. It supports modification anywhere in the document by putting a gap in the underlying stream of text and then putting the changes into the gap. As the app inserts new messages into the Document it creates lots and lots of Gaps.
The actual text to display has to exist somewhere. There is probably a better way to implement a huge text pane, but the default JTextPane will look, to the profiler, like a memory leak. If you have 600kb of log messages, its going to take at least 600kb of memory somewhere.
You should know that the Java Console uses a PlainDocument with GapContent$MarkData and just having the console open with lots of data in it will cause this "memory leak" to appear. Clear the console to see the number of MarkData drop back to acceptable levels.

Lag due to threads swapping

I have come across some recent lag spikes in a game I have been developing. It is consistent, happens around the same time. Using the java profiler jvisualvm I have found it occurs at the same time a particular thread seems to restart or something (AWT-EventQueue-0):
Other than that, there is no visible cause, not in heap usage, processor use, memory space, or method uses. It will sometimes cause a ConcurrentModificationException when drawing my array of objects, but this should only happen with substantial lag, and my game is hardly intensive.
I don't recall performing any recent changes to the project, however I have carried out the following recently:
Updated java to the latest version
Downloaded latest version of JDK7 (though it is not being used in this project)
Fixed bug with eclipse that occurred as a result of installing JDK7 (removed 256m limit
in eclipse.ini)
I am running Eclipse Indigo-service-1 on 32 bit XP. My processors are barely used.
It seems you are doing too much on the Event Dispatch Thread (EDT). AWT-Event-Queue-0 looks to be the EDT. Additionally, your last comment says
...it seems the lag spike only occurs when I draw my game board to an image first rather than directly to the component.
You'll need to push some of your computations to other threads, and it sounds like drawing the game board is a good choice for this. Also, any AI you may have.
Your keyboard & mouse handlers run on the EDT, and the graphics updates need to too. But you can pre-render to an image (like you are currently doing) outside the EDT. And you can send the keyboard & mouse events to another thread via a BlockingQueue.
One other thing you could do is decouple your game-update rate from your frame-update rate.
But without any details, I can't give much more advice.
Update: (just read your bit about ConcurrentModificationException)
This can be caused by two different things:
you are updating a collection (like your ArrayList) in a different thread from the one you are reading it in; or
you are iterating through said collection and updating it in the loop.
Point 2 is easy to fix; but I'm afraid I can't teach thread safety in such a short amount of space.

How can I prevent my Java program from lagging while other applications are running?

I wrote a simple code in Java that uses the Robot class to move the mouse according to some conditions.
Although the code works nicely, there seems to be a 'lag' when other applications are running.
I think Java has some issues posting system messages.
Is there a workaround to avoid this?
Before you start thinking about reducing the lag, you must first understand it's causes. I'll present the answer(s) in a fashion in which you can understand the "why" along with the "what to do".
By your description that the lag only occurs when other programs are running along with your robot, the most likely causes for the lag are:
Lack of system resources - Too many things running at the same time, consuming too much memory/processing-power, thus making the OS slow-down some programs in order to be able to run the others.
What to do: To try to fix such issues, you can try to optimize your code, to make it use less memory/processing power, thus reducing the cause of the lag, with implicitly reduces the lag itself. Unfortunetly tough, it's hard to legally do the same for any 3rd party programs, so the lag can hardly be completely removed if the concurrent applications are not yours.
Concurrency regarding a non-replicable, non-shareable component - One or more components that cannot be accessed by more than one process at a time and that cannot be cloned into multiple instances needs to be used by more than one process that is running. While one process takes control of it, any other processes have no choice but wait for the component to be freed.
What to do: In this case, there hardly is any legal method other than to reduce the concurrent process's priority while increasing your's (effectively slowing them down in order for your program to run faster), or shut them down completely.
How to do: To increase your process's priority, this is the code to set it at 80% (default is usually 50%), inset at your main():
Thread.currentThread().setPriority((int)(Thread.MAX_PRIORITY*0.8));
Note: You can set your process to "never" let go of whatever components it needs, using Thread.MAX_PRIORITY without multiplying by 0.8, but that is unrecommended, as it will pretty much pause any process that requires the components (quasi-same to shutting them down while yours is running), and if your program hangs, for whatever reason, so will those, as the components are never released.

An applet gets Windows 7 to freeze completely

I've got an applet which does something which gets Windows 7 to freeze completely, the mouse pointer no longer responds, ctrl-alt-del no longer works etc.
When I open the task manager, it doesn't show any significant CPU load or excessive usage of memory.
The freeze sometimes happens when debugging on Eclipse as well, but not always.
I'm not quite sure where I should set breakpoints yet since it's a pretty big GUI application.
Could this be a bug in the JVM? Isn't it supposed to be impossible for an applet to do something like this?
Edit: To answer my own question, I found the bug in Eclipse, and it seems that the call to Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null) gets the whole system to freeze, which is pretty surprising since the Excel file is only 1 MB. Maybe the clipboard isn't really designed for situations like this.
Use jStack to generate a Thread Dump. That way you will know what the code is doing. To use it just:
C:\your_java_bin_folder> jstack -l <process-id>
You can get the process id from the Task Manager. jStack is part of the jdk (as far as I know since 1.5).

Categories

Resources