I'm debugging legacy code that displays a small amount data (< 100 entries) using a JXTable. All the functionality works but when there is at least one entry in the table, the CPU usage climbs to over 95% iff the pane is displayed. Instrumentation has shown that the highlight method is called several times per millisecond.
The highlight method is called only when the table is visible (a different tab is selected), which makes sense.
I am in the process of trying to duplicate it in a small sample, but that's not working yet. I just wondered if anyone out there has seen similar behavior and came up with a solution.
Library: swingx-1.0.jar
Java: jdk1.8.0_144
This was my* code. In the cellRenderer() there was a call to setRowHeight(). This causes the pane to be marked dirty. So the next cycle, it does a repaint(). The repaint() calls my cellRenderer(). Thus creating a repaint loop whenever the pane is visible. The solution was to remove the call to setRowHeight() since it wasn't needed anyway.
*I say my code because I am now responsible for it. This problem was created long before I joined the company.
Related
I have been exploring the Sequential Transition from JavaFX, and it seems a perfect fit for what I need. So, I am working on a JavaFX desktop application that essentially shows some pictures, text, and plays some video and audio files. Now, since some of those items are presented sequentially, I have decided to use the sequential transition. Now, I just run into a problem that I have tried to address but it does not seem to work as expected. Let's imagine that the sequence in which those items are presented is predefined in a Map. When those items are presented to the user, he/she needs to provide an answer, and if that is correct you can think that the item can be categorized as Done. However, in some of the cases I need that the user repeats some of the items for learning purposes. And that has to be done 'on-the-fly' since I have another window in which someone else decides which items must be repeated. As you can see, this requires some modification of the sequential transition at runtime. Is there any suggestions on how to address this challenge?
Thanks,
As the documentation for SequentialTransition states:
It is not possible to change the children of a running SequentialTransition. If the children are changed for a running SequentialTransition, the animation has to be stopped and started again to pick up the new value.
I have a sizable Java app that creates complex data structures describing a drawing, starting with the raw time-stamped data points and displaying the drawing, analyzing it, etc.
When I try to process a series of these drawings, I'm clearly hanging on to memory in the form of a JScrollPane that's used to hold the drawing, but I cannot figure out why. The variable holding the scroll pane is reassigned with each new file loaded, but I noticed that the swing RepaintManager is maintaining a list of the previously displayed panes in its invalidComponents list. This seems then to hang onto the storage for each drawing, and before long I've got 1GB of memory in use when I'm processing files serially and should thus never have more than one drawing's worth of memory in use.
I got a memory dump and have analyzed with the Eclipse memory analyzer and with YourKit.
Here's what I believe to be the smoking gun as displayed by Eclipse's memory analyzer:
Have spent quite a while trying to drill down into this problem. I would be most grateful for any suggestions about where my error may lie or how to work around the problem.
I realize it's difficult to tell without being able to dig into the code, but if there are even any general suggestions/cautions about where to look, that would be great.
As #MadProgrammer suggests, your present code presumably replaces the existing JScrollPane instance:
scrollPane = new JScrollPane(view);
Instead, update the viewport component via setViewportView():
scrollPane. setViewportView(view);
Even better, update the content of view directly. Details would depend on your implementation, but validate() and repaint() represent one approach.
I have a program with GUI with segment that can be large and contain a lot of objects. One of the features of my program is to "close" that segment and create a new one.
This whole segment is attached to the program by only one JPanel and an ArrayList. If I dispose of/set those two to null there should be no way to access the any of the JPanels childen (one of which are complex object extending GUI components, but also containing a lot of variables).
If I'm correct, all of JPanels childeren will be collected by garbage collector.
However, what happens to the children of the children? I have some "families" that go up to 5-6 "generations". Will they be deleted only upon GC's 5th (or 6th) pass, or will it detect the whole "family" as unacessible and collect it all at once (or upon it's first pass)?
EDIT: Another minor question: Is there a method for swing component that will remove all of it's children?
For an empirical approach, exercise your program repeatedly and look for the pattern shown here, in which the memory consumed fails to return to baseline.
In contrast, this example returns to the baseline after each cycle.
The comments to your question do a good job of addressing the deletion issue. But, if you're still curious about removing a component's children without removing the component, the answer is no, as seen in the JComponent documentation (I'm assuming you're on Java 7, if not you can easily change to the proper version of Java). If you want to quickly and easily remove just the children from a component without removing the component itself, I recommend just re-initializing the component.
I am rendering rather heavy object consisting of about 500k triangles. I use opengl display list and in render method just call glCallList. I thought that once graphic primitives is compiled into display list cpu work is done and it just tells gpu to draw. But now one cpu core is loaded up to 100%.
Could you give me some clues why does it happen?
UPDATE: I have checked how long does it take to run glCallList, it's fast, it takes about 30 milliseconds to run it
Most likely you are hitting the limits on the list length, which are at 64k verteces per list. Try to split your 500k triangles (1500k verteces?) into smaller chunks and see what you get.
btw which graphical chips are you using? If the verteces are processed on CPU, that also might be a problem
It's a bit of a myth that display lists magically offload everything to the GPU. If that was really the case, texture objects and vertex buffers wouldn't have needed to be added to OpenGL. All the display list really is, is a convenient way of replaying a sequence of OpenGL calls and hopefully saving some of the function call/data conversion overhead (see here). None of the PC HW implementations I've used seem to have done anything more than that so far as I can tell; maybe it was different back in the days of SGI workstations, but these days buffer objects are the way to go. (And modern OpenGL books like OpenGL Distilled give glBegin/glEnd etc the briefest of mentions only before getting stuck into the new stuff).
The one place I have seen display lists make a huge difference is the GLX/X11 case where your app is running remotely to your display (X11 "server"); in that case using a display list really does push all the display-list state to the display side just once, whereas a non-display-list immediate-mode app needs to send a bunch of stuff again each frame using lots more bandwidth.
However, display lists aside, you should be aware of some issues around vsync and busy waiting (or the illusion of it)... see this question/answer.
I know that GUI code in Java Swing must be put inside
SwingUtilities.invokeAndWait or SwingUtilities.invokeLater.
This way threading works fine.
Sadly, in my situation, the GUI update it that thing which takes much longer than background thread(s). More specific: I update a JTree with about just 400 entries, nesting depth is maximum 4, so should be nothing scary, right? But it takes sometimes one second! I need to ensure that the user is able to type in a JTextPane without delays. Well, guess what, the slow JTree updates do cause delays for JTextPane during input. It refreshes only as soon as the tree gets updated.
I am using Netbeans and know empirically that a Java app can update lots of information without freezing the rest of the UI.
How can it be done?
NOTE 1: All those DefaultMutableTreeNodes are prepared outside the invokeAndWait.
NOTE 2: When I replace invokeAndWait with invokeLater the tree doesn't get updated.
NOTE 3: Fond out that recursive tree expansion takes far the most time.
NOTE 4: I'm using custom tree cell renderer, will try without and report.
NOTE 4a: My tree cell renderer uses a map to cache and reuse created JTextComponents, depending on tree node (as a key).
CLUE 1: Wow! Without setting custom cell renderer it's 10 times faster. I think, I'll need few good tutorials on writing custom tree cell renderers. Sadly, I need a custom cell renderer.
This tutorial involving lazy loading might help, I'll work this through.
[There are some details missing, such as: what type of processing is happening each time the user updates the JTextPane? Is the whole tree being rebuilt?]
Anyway, what has worked for me in the past (when I experienced significant slowdown due to JTree updates) is that I rolled out my own TreeModel.
Most programmers choose to use DefaultTreeModel. This is indeed an off-the-shelf solution that works well in most cases. However, it is quite slow when significant parts of the tree needs to be updated. Obviously, Writing your own TableModel is more work than using a canned solution, but it is much less painful than you think.
In particular, my custom tree model is fast because it does not build any tree, per-se. It just observes my domain model and computes the answers to the method invoked on it (getChild(), getParent(), ...) by extracting the relevant information from that model. Try it. It works like a charm.
I do not know why it only works with invokeAndWait() (this is strange), but a simple hack would be to invoke this method in a new background thread.
I would also advise you not to populate all the tree at once. This is often a huge amount of work that just cannot be easily sped up. Instead, update only those nodes that are visible and update more nodes as the user expands them.