GRECLIPSE
  1. GRECLIPSE
  2. GRECLIPSE-1633

Full build of project produces a massive number of ClassNodes that don't seem to go away

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.8.0.Release
    • Component/s: Compiler Integration
    • Labels:
      None
    • Number of attachments :
      0

      Description

      During profiling, I noticed that after a full build of a project, a massive number of ClassNodes are created, but not destroyed even after the project is closed. For example, the GPars project will contrinbute about 70,000 ClassNodes after a build that do not go away when it is closed.

      This does not look like a leak because the number of used ClassNodes does not increase after the first full build. But, the ClassNodes are not being cleaned up when they should.

        Issue Links

          Activity

          Hide
          Andrew Eisenberg added a comment -

          It looks like most (all?) of these references come from fixed core types of Groovy. All of the DefaultGroovyMethods, IOGroovyMethods, java.util.List, java.util.ArrayList and other commmon, shared classes are loaded once and used between all projects. They are not cleaned up and just stick around even after they are no tbeing used directly any more (since they may be used again in the future).

          Show
          Andrew Eisenberg added a comment - It looks like most (all?) of these references come from fixed core types of Groovy. All of the DefaultGroovyMethods , IOGroovyMethods , java.util.List , java.util.ArrayList and other commmon, shared classes are loaded once and used between all projects. They are not cleaned up and just stick around even after they are no tbeing used directly any more (since they may be used again in the future).
          Hide
          Andrew Eisenberg added a comment -

          Interesting thing is that it seems that the GPars project triggers the massive jump in ClassNode instances. Full builds of other small and trivial projects keep ClassNode numbers under 6,000 instances.

          Show
          Andrew Eisenberg added a comment - Interesting thing is that it seems that the GPars project triggers the massive jump in ClassNode instances. Full builds of other small and trivial projects keep ClassNode numbers under 6,000 instances.
          Hide
          Andrew Eisenberg added a comment -

          To be clear, it is only a full build that triggers this behavior. Incremental builds do not. Interacting with a groovy file in the editor does not. Both of these actions do cause a minor increase in ClassNodes, but they go away when the project is closed.

          What is it about GPars that causes this? Could it be the gradle integration?

          Show
          Andrew Eisenberg added a comment - To be clear, it is only a full build that triggers this behavior. Incremental builds do not. Interacting with a groovy file in the editor does not. Both of these actions do cause a minor increase in ClassNodes, but they go away when the project is closed. What is it about GPars that causes this? Could it be the gradle integration?
          Hide
          Andrew Eisenberg added a comment -

          Just raised GROOVY-6171 for memory issues that are coming from the compiler, not Groovy-Eclipse.

          Show
          Andrew Eisenberg added a comment - Just raised GROOVY-6171 for memory issues that are coming from the compiler, not Groovy-Eclipse.
          Hide
          Andrew Eisenberg added a comment -

          Another interesting tidbit. It seems like the JDTClassNodes created by the HighlightingExtenderRegistry and the OutlineExtenderRegistry are backed by an extremely huge Resolver (212 Mb!). These are two groovy classes inside of Groovy-Eclipse that are loaded when a Groovy Editor is opened (or possibly earlier). But, if a groovy editor is opened on startup, these classes will be loaded before any groovy compiler classes are loaded. I don't exactly know why the JDTResolver is so big and more importantly, I'm not sure why a JDTResolver is being used at all.

          Rather than delve into the reason why this is happening, I decided to simply convert these classes into Java. The problem has gone away.

          Show
          Andrew Eisenberg added a comment - Another interesting tidbit. It seems like the JDTClassNodes created by the HighlightingExtenderRegistry and the OutlineExtenderRegistry are backed by an extremely huge Resolver (212 Mb!). These are two groovy classes inside of Groovy-Eclipse that are loaded when a Groovy Editor is opened (or possibly earlier). But, if a groovy editor is opened on startup, these classes will be loaded before any groovy compiler classes are loaded. I don't exactly know why the JDTResolver is so big and more importantly, I'm not sure why a JDTResolver is being used at all. Rather than delve into the reason why this is happening, I decided to simply convert these classes into Java. The problem has gone away.
          Hide
          Andrew Eisenberg added a comment -

          I am going to convert the remaining groovy files into Java. There are 2: FilePartReader and GroovyShellLaunchDelegate.

          Show
          Andrew Eisenberg added a comment - I am going to convert the remaining groovy files into Java. There are 2: FilePartReader and GroovyShellLaunchDelegate.
          Hide
          Andrew Eisenberg added a comment -

          Just a note that this is not related to the original point of this issue. However, it does significantly reduce memory usage.

          Show
          Andrew Eisenberg added a comment - Just a note that this is not related to the original point of this issue. However, it does significantly reduce memory usage.
          Hide
          Andrew Eisenberg added a comment -

          The main problem that I am seeing here is not the massive number of ClassNodes being generated, but rather that there are some massive ClassNodes. Raised GROOVY-6184 to fix this in the compiler. Already fixed in greclipse 2.1.x, 2.0.x, and 1.8.x.

          Problem is that ClassHelper instantiates Enum and Annotation differently from all other ClassNodes. They are lazily initialized, whereas all other class nodes are generated directly from Class objects. This was because historically, groovy had to handle Java 1.4 as well as 1.5. 1.4 support has been dropped, so this distinction is no longer relevant.

          Problem is that in greclipse, the first time that an enum or annotation type is declared in source, these ClassNodes in ClassHelper are resolved. They are resolved against the current project and remain fixed that way no matter what happens, even if that project is subsequently deleted from the workspace. This is the cause of the memory leak that I discovered earlier.

          This problem also happens in the standalone compiler, but the affects are much less bad.

          Show
          Andrew Eisenberg added a comment - The main problem that I am seeing here is not the massive number of ClassNodes being generated, but rather that there are some massive ClassNodes. Raised GROOVY-6184 to fix this in the compiler. Already fixed in greclipse 2.1.x, 2.0.x, and 1.8.x. Problem is that ClassHelper instantiates Enum and Annotation differently from all other ClassNodes. They are lazily initialized, whereas all other class nodes are generated directly from Class objects. This was because historically, groovy had to handle Java 1.4 as well as 1.5. 1.4 support has been dropped, so this distinction is no longer relevant. Problem is that in greclipse, the first time that an enum or annotation type is declared in source, these ClassNodes in ClassHelper are resolved. They are resolved against the current project and remain fixed that way no matter what happens, even if that project is subsequently deleted from the workspace. This is the cause of the memory leak that I discovered earlier. This problem also happens in the standalone compiler, but the affects are much less bad.
          Hide
          Andrew Eisenberg added a comment -

          With these changes, memory problems are less severe. So, resolving this issue.

          Show
          Andrew Eisenberg added a comment - With these changes, memory problems are less severe. So, resolving this issue.

            People

            • Assignee:
              Andrew Eisenberg
              Reporter:
              Andrew Eisenberg
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: