1 Apr 2010 01:52
Re: Memory leak in jEdit ?
Vampire (jEdit <Vampire0 <at> gmx.net>
2010-03-31 23:52:49 GMT
2010-03-31 23:52:49 GMT
For me the font substitution doesn't make any difference. The error
happens with and without the option being active.
But I found out how to reliably reproduce the problem and also that we possibly don't have a problematic leak here because it is very short-living.
JProfiler tells me the allocation of that char[] was done in org.gjt.sp.util.SegmentBuffer.ensureCapacity() with one allocation.
The reference hold to it is in sun.font.GlyphLayout though.
To be concrete, the char[] is still available in an instance of sun.font.TextRecord.
This TextRecord is an instance variable of a GlyphLayout.
The GlyphLayout in question is referenced as static field "cache" in class GlyphLayout.
If someone calls GlyphLayout.done(GlyphLayout) the given GlyphLayout is referenced as cache and the next time someone calls GlyphLayout.get(LayoutEngineFactory) this cached GlyphLayout is returned and reused and the cache reference is set to null.
Actually org.gjt.sp.jedit.syntax.Chunk.addGlyphVector(Font, FontRenderContext, char[], int, int) calls java.awt.Font.layoutGlyphVector(FontRenderContext, char[], int, int, int) which in turn first calls GlyphVector.get(null), then layouts the glyphs with GlyphVector.layout(...) and then calls GlyphLayout.done(GlyphLayout) which causes that GlyphLayout to be stored in the cache reference.
This means, as soon as some other text is displayed, the memory is freed as the TextRecord then has the contents of the next file.
So if you have some buffer open with text in it, you will not notice any memory leak as the GlyphLayout is reused as soon as you display some other text. If you have only Untitled-1 without any text open, you should be able to reproduce the bug reliably with Java 6 running. I even was able to reproduce the bug this way with 4.3.1, so it was no change in jEdit, it was just not discovered yet.
The only difference I see between the Java 5 and Java 6 version of GlyphLayout is that the cache field is volatile in Java 6. In Java 5 the cache is null if I break jEdit with leak and look at the variable. In Java 6 cache is set to the old GlyphLayout.
One solution to this would be to call sun.font.GlyphLayout.get(null); after layoutGlyphVector() in Chunk:494, which will cause cache to be set to null and as we don't reference it, it can be garbage-collected.
Though we 1. would use a sun. class which is not recommended and can break with any Java update without prior notice and 2. we would thereby disable the mechanism to reuse GlyphLayout instances for saving memory and performance.
Is there maybe a better option?
Do we really need to "fix" this?
Maybe we should look if this is reported as leak already and if not report it as major leak. It would e. g. be sufficient in GlyphLayout.done(GlyphLayout) to clear the char[] in the TextRecord.
Regards
Vampire
Matthieu Casanova schrieb:
But I found out how to reliably reproduce the problem and also that we possibly don't have a problematic leak here because it is very short-living.
JProfiler tells me the allocation of that char[] was done in org.gjt.sp.util.SegmentBuffer.ensureCapacity() with one allocation.
The reference hold to it is in sun.font.GlyphLayout though.
To be concrete, the char[] is still available in an instance of sun.font.TextRecord.
This TextRecord is an instance variable of a GlyphLayout.
The GlyphLayout in question is referenced as static field "cache" in class GlyphLayout.
If someone calls GlyphLayout.done(GlyphLayout) the given GlyphLayout is referenced as cache and the next time someone calls GlyphLayout.get(LayoutEngineFactory) this cached GlyphLayout is returned and reused and the cache reference is set to null.
Actually org.gjt.sp.jedit.syntax.Chunk.addGlyphVector(Font, FontRenderContext, char[], int, int) calls java.awt.Font.layoutGlyphVector(FontRenderContext, char[], int, int, int) which in turn first calls GlyphVector.get(null), then layouts the glyphs with GlyphVector.layout(...) and then calls GlyphLayout.done(GlyphLayout) which causes that GlyphLayout to be stored in the cache reference.
This means, as soon as some other text is displayed, the memory is freed as the TextRecord then has the contents of the next file.
So if you have some buffer open with text in it, you will not notice any memory leak as the GlyphLayout is reused as soon as you display some other text. If you have only Untitled-1 without any text open, you should be able to reproduce the bug reliably with Java 6 running. I even was able to reproduce the bug this way with 4.3.1, so it was no change in jEdit, it was just not discovered yet.
The only difference I see between the Java 5 and Java 6 version of GlyphLayout is that the cache field is volatile in Java 6. In Java 5 the cache is null if I break jEdit with leak and look at the variable. In Java 6 cache is set to the old GlyphLayout.
One solution to this would be to call sun.font.GlyphLayout.get(null); after layoutGlyphVector() in Chunk:494, which will cause cache to be set to null and as we don't reference it, it can be garbage-collected.
Though we 1. would use a sun. class which is not recommended and can break with any Java update without prior notice and 2. we would thereby disable the mechanism to reuse GlyphLayout instances for saving memory and performance.
Is there maybe a better option?
Do we really need to "fix" this?
Maybe we should look if this is reported as leak already and if not report it as major leak. It would e. g. be sufficient in GlyphLayout.done(GlyphLayout) to clear the char[] in the TextRecord.
Regards
Vampire
Matthieu Casanova schrieb:
I'll try tomorow, I don't remember if the font substitution is active but it is possible since I tried the option. In fact the leak is strange, it doesn't seems to grow. When I open a big file then close it, my jEdit grow to 180/190MB, but if I open any other file including big files it doesn't grow anymore like if the JVM was keeping a cache of fonts, that's very strange Matthieu 2010/3/31 Marcelo Vanzin <vanza <at> users.sourceforge.net>:On Wed, Mar 31, 2010 at 2:37 AM, Matthieu Casanova <chocolat.mou <at> gmail.com> wrote:------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-devso there may be a bug in Sun's JDK 1.6 if it doesn't happens with Java 1.5 (I also tried with open-jdk 1.6 and have the same problem). If I'm not wrong there was a change about fonts in the TextArea between 4.3.x and 4.4 isn't it ? maybe this made the bug appear ?I changed something in that area but the feature is off by default. Can you check if you have it enabled? (It's the "font substitution" stuff in the TextArea pane.) Although I'm using trunk with that option enabled, on Java 1.6, and haven't noticed any leaks, but then I'm not opening huge files. -- Marcelo Vanzin mmvgroups <at> gmail.com "Life's too short to drink cheap beer." ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- ----------------------------------------------- jEdit Developers' List jEdit-devel <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jedit-devel
------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev
-- -- ----------------------------------------------- jEdit Developers' List jEdit-devel <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jedit-devel
... so a java-based installer would be really
> cool in order to create the windows installer on Mac OS (as in my case).
>
> Okay, so I followed two options
>
> +) using the free IZPack installer which looks good (but I have never
> used it)
>
> +) using a commercial installer such as install4j (which I used for a
> couple of years)
>
> At that point I was wondering if ej-technologies (the company behind
> install4j) would provide a free license for open-source projects and
> decided that I could ask them directly - and yes they would be
> interested in it assuming that this donation is somehow visible on the
> web site and/or blog
>
> Using install4j would have a few advantages such as
>
> +) native application launchers for Windows, Linux and Mac are supplied
> out-of-the-box
>
> +) install4j also provides shell and rpm based installers
>
> +) install4j comes with Ant integration
>
> +) install4j supports building the installers cross-platform, i.e. I'm
> creating all my installers on Mac OS
>
> Having said that
>
> +) I asked as a private person and did not mention any project since I
> have no JEdit hat
>
> +) I'm in no way affiliated with ej-technologies
>
> +) would it be acceptable for the community to rely on free but
> commercial tools? It is perfectly okay for some projects (as in Apache
> land for IntelliJ or JIRA) but might be a no-go for other projects
>
> Thanks in advance,
>
> Siegfried Goeschl
>
> ------------------------------------------------------------------------------
> Download Intel® Parallel Studio Eval
> Try the new software tools for yourself. Speed compiling, find bugs
> proactively, and fine-tune applications for parallel performance.
> See why Intel Parallel Studio got high marks during beta.
>
RSS Feed