sun.awt.X11.XEvent is creating 600 MB of char[] for no good reason (original) (raw)
Anthony Petrov anthony.petrov at oracle.com
Thu Oct 27 07:13:01 PDT 2011
- Previous message: sun.awt.X11.XEvent is creating 600 MB of char[] for no good reason
- Next message: sun.awt.X11.XEvent is creating 600 MB of char[] for no good reason
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi all,
I agree, fixing the root cause of the issue makes sense. I've just filed a new CR to cover this fix.
The XWrapperBase descendants are indeed all generated at build time, so we only need to fix the WrapperGenerator class itself.
The patch sent by Federico looks good to me. Thank you very much for another contribution!
-- best regards, Anthony
On 10/27/11 08:03, Oleg Sukhodolsky wrote:
If you do not see these classes in the repo then they are generated in build time. Unfortunately I do not have a repo right now so I can not check this :(
Oleg. On Thu, Oct 27, 2011 at 2:05 AM, Federico Tello Gentile <federicotg at gmail.com> wrote: Here's a patch to use StringBuilder. It also sets an initial size to reduce char[] copying when appending.
I ran the generator locally and checked the generated code. As I don't know if those java files are generated on every build or if they were generated just once with certain input files and committed to the repo, I did not go any further. I hope it is at least a starting point. El jue, 27-10-2011 a las 00:14 +0400, Oleg Sukhodolsky escribió: Yep, you are right. It is a WrapperGenerator who should be fixed. And after that we need to regenerate all wrappers (if they are not generated during build).
Oleg. On Wed, Oct 26, 2011 at 11:27 PM, Federico<federicotg at gmail.com> wrote: Almost all sun.awt.X11.XWrapperBase subclasses have similarly horrible getFieldsAsString() implementations, but they are all automatically generated (which is a relief as there was no human being actually writing such code).
They all say at the beginning: // This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead ! My guess is in file /openjdk/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java in line 678 public void writeToString(StructType stp, PrintWriter pw) { starts the code generating bit.
2011/10/26 Oleg Sukhodolsky<son.two at gmail.com>: +1 to Artem. It is better to fix this too. Oleg. On Wed, Oct 26, 2011 at 7:34 PM, Artem Ananiev<artem.ananiev at oracle.com> wrote: On 10/26/2011 7:26 PM, Anthony Petrov wrote:
On 10/26/2011 7:12 PM, Artem Ananiev wrote:
On 10/21/2011 4:00 PM, Anthony Petrov wrote:
Indeed, this is a nasty issue. Thanks for spotting it. You may notice that in most other places where something is logged, the code usually checks whether logging is enabled for a certain level of logging, e.g.:
if (shapeLog.isLoggable(PlatformLogger.FINER)) { shapeLog.finer( "*** INFO: Setting shape: PEER: " + this + "; WINDOW: " + getWindow() + "; TARGET: " + target + "; SHAPE: " + shape); } So basically, we could simply wrap the line in question into a similar if(){} statement to make sure it gets executed only when the FINEST level of logging is enabled. A similar solution may also apply to another call to enableLog.finer() in the same method just a few lines below. Although the fix has been already pushed to the workspace, let me wonder if, in addition to wrapping the logging calls with the "if ()" checks, we should have also rewritten isEventDisabled() to use StringBuilder? I guess you really mean the XEvent.getFieldsAsString() here [1], right? Yes, exactly. Thanks for this correction. Possibly. But with Federico's fix this method now only gets called when logging is enabled, and as such the impact of the issue is limited. I realize that. My point is that we just hide the problem, or make it less visible, or make it appear less frequently - whatever you prefer. However, the problematic code that contains char[] allocation is still in the workspace, and we know how often people use the current code as a pattern for future changes... Thanks, Artem [1] http://mail.openjdk.java.net/pipermail/awt-dev/2011-October/001952.html -- best regards, Anthony
Thanks, Artem Could you make a patch, test it, and post it to this mailing list for review please? -- best regards, Anthony On 10/21/2011 7:10 AM, Federico Tello Gentile wrote: Hi. I'm running java -version java version "1.7.0147-icedtea" OpenJDK Runtime Environment (IcedTea7 2.0pre) (7
b147-2.0pre6-1ubuntu1) OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode) and profiling a simple Swing application. Just by opening a JFrame and moving the mouse over it for 10 secods I see 600 MB of char[] being created. I can easily create several terabytes or those if I move the mouse a little longer. Thanks to the incredibly efficient garbage collector the application performance is not visibly affected on my 4GB quad core machine. The problem is an incredibly inefficient method sun.awt.X11.XEvent.getFieldsAsString() which I pasted at the end of this message. The way it it handling string concatenation forces StringBuilder to grow many times and ends up calling Arrays.copyOf a lot of times. It is being called by the sun.awt.X11.XWrapperBase.toString() just for the sake of logging here: sun.awt.X11.XComponentPeer protected boolean isEventDisabled(XEvent e) enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable")); The worse part is that even if logging is disabled and nothing at all is ever logged, the toString is called anyway and all those char[] are created anyway. Here's a NetBeans profiler memory snapshot. http://ubuntuone.com/4xkprEzadUM4sUSdAnWlN5 This does not happen at all if I run the same profiling with this openjdk version java -version java version "1.6.023" OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre10-0ubuntu5) OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode) I hope we can do something to improve this situation. I guess all Swing applications are affected. I look forward for any comments. Here's the "thing"... --------------------------------------------------- String getFieldsAsString() { String ret=""; ret += ""+"type = " + XlibWrapper.eventToString[gettype()] +", "; ret += ""+"xany = " + getxany() +", "; ret += ""+"xkey = " + getxkey() +", "; ret += ""+"xbutton = " + getxbutton() +", "; ret += ""+"xmotion = " + getxmotion() +", "; ret += ""+"xcrossing = " + getxcrossing() +", "; ret += ""+"xfocus = " + getxfocus() +", "; ret += ""+"xexpose = " + getxexpose() +", "; ret += ""+"xgraphicsexpose = " + getxgraphicsexpose() +", "; ret += ""+"xnoexpose = " + getxnoexpose() +", "; ret += ""+"xvisibility = " + getxvisibility() +", "; ret += ""+"xcreatewindow = " + getxcreatewindow() +", "; ret += ""+"xdestroywindow = " + getxdestroywindow() +", "; ret += ""+"xunmap = " + getxunmap() +", "; ret += ""+"xmap = " + getxmap() +", "; ret += ""+"xmaprequest = " + getxmaprequest() +", "; ret += ""+"xreparent = " + getxreparent() +", "; ret += ""+"xconfigure = " + getxconfigure() +", "; ret += ""+"xgravity = " + getxgravity() +", "; ret += ""+"xresizerequest = " + getxresizerequest() +", "; ret += ""+"xconfigurerequest = " + getxconfigurerequest() +", "; ret += ""+"xcirculate = " + getxcirculate() +", "; ret += ""+"xcirculaterequest = " + getxcirculaterequest() +", "; ret += ""+"xproperty = " + getxproperty() +", "; ret += ""+"xselectionclear = " + getxselectionclear() +", "; ret += ""+"xselectionrequest = " + getxselectionrequest() +", "; ret += ""+"xselection = " + getxselection() +", "; ret += ""+"xcolormap = " + getxcolormap() +", "; ret += ""+"xclient = " + getxclient() +", "; ret += ""+"xmapping = " + getxmapping() +", "; ret += ""+"xerror = " + getxerror() +", "; ret += ""+"xkeymap = " + getxkeymap() +", "; ret += "{" + getpad(0) + " " + getpad(1) + " " + getpad(2) + " " + getpad(3) + " " + getpad(4) + " " + getpad(5) + " " + getpad(6) + " " + getpad(7) + " " + getpad(8) + " " + getpad(9) + " " + getpad(10) + " " + getpad(11) + " " + getpad(12) + " " + getpad(13) + " " + getpad(14) + " " + getpad(15) + " " + getpad(16) + " " + getpad(17) + " " + getpad(18) + " " + getpad(19) + " " + getpad(20) + " " + getpad(21) + " " + getpad(22) + " " + getpad(23) + " " + "}"; return ret; }-- Mi clave pública http://keyserver.ubuntu.com:11371/pks/lookup?op=get&search=0x157673683A51700A
- Previous message: sun.awt.X11.XEvent is creating 600 MB of char[] for no good reason
- Next message: sun.awt.X11.XEvent is creating 600 MB of char[] for no good reason
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]