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.
Related
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.
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 would like to implement undo/redo in a small paint application. It seems the Command Pattern fits the use nicely, but I am unsure how to best implement it.
As I understand the pattern, it is necessary to include in each command:
The details of the paint operation for purposes of redo (e.g. Line -> start & end points, free form line -> GeneralPath)
The state of the component prior to the change for undo. In this case, that will be a small snapshot image of the area affected by the command.
My understanding based on that is that each command needs to be 'atomic' or self contained, with all the information needed for undo/redo that operation.
Unfortunately that would require storing more information than I'd first anticipated. For a line we must also account for things like the Color, Stroke and RenderingHints used to draw it initially. This turns my 'simple little commands' into something ..more bulky in memory, and with more boiler-plate code to churn out (each will be a serializable bean1).
For reasons of memory conservation (mostly) I was wanting to 'cheat' on the specification of the commands. Perhaps take a backup of the entire drawing area every 100th update, but otherwise store no part of the changed image, and simply rebuild the last (up to) 100 commands for each new paint operation. But that seems problematic to ensure that the state of the Graphics object is right before painting each part - this part might require a line, but the RenderingHints were changed 4 commands ago, the Color was changed 98 commands ago, while the Stroke has remained the same for the last 227 commands.
Pursuing a more memory efficient command seems to throw the pattern right out the window in terms of being 'atomic'. That in turn leads to difficulties in determining the earliest command that might affect the rendering.
Should I:
Look for a new pattern?
Attempt to implement my peculiar needs by tweaking the pattern?
Toss all this in the waste bin as premature optimization and code it in the simplest (and most memory consuming) way that sticks to the command pattern as defined?
Update
"each will be a serializable bean" On 2nd thoughts, no. I did dome checks to find that a Graphics2D (which neatly encapsulates many parameters used when drawing) is not serializable. Further, a BasicStroke is serializable, but the thickness of the stroke is not stored. I could create serializable versions of many of the attributes but it seems to make for a lot more code, so I'm going to abandon that spec. as well. I will only attempt to store a reference to a BufferedImage at run-time.
I would stick with command pattern and first try a naive solution (=the most memory-hungry). For some graphical operations it may be even necessary to keep a copy of the entire image in the command object (eg. think of filters). This is a common problem also in professional image editing applications, they often have a memory or step limit of last commands that are remembered. And if the memory consumption is really large you may think of swapping the oldest entries in command-history to file system. I think user will not mind waiting a second until the change is undone.
Maybe, it would be better not to store copy of entire image in command, but store only copy of area, which is changing by command. Of course, this is not a panacea
a while ago i wrote an editor for a navigation graph that represented the paths inside (and between) buildings. it was stored inside a Graph-class.
the edges, for example were stored in one collection per floor, plus one collection for the ones that were between floors.
to draw them (only the current floor) or save them to disk (all of them), i needed to get at them from the outside. for that i implemented methods like callWithAllEdges and callWithAllEdgesIn, the latter taking a parameter to specify a floor.
those methods took a functor (at least i called it that), that was then called with the edges.
this is what drawing the edges of one floor looked like:
graph.callWithAllEdgesIn(id, new Functor<Edge>() {
public void call(Edge e) {
drawEdge(g,e);
}
});
this is a bit long-winded, of course. might be a problem with java and not with my solution though, i dont know.
another way would have been to just make a method that puts references to all the needed edges into a new collection and then iterate over that, i guess. seemed kind of wrong to me though.
my question is: how could i have solved that better?
Your current design is perfectly reasonable. Another option is to provide an Iterable/Iterator. That way you don't need to copy everything into a new list, but can instead lazily step through your internal lists.
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.