• Bug
  • Status: Closed
  • 2 Major
  • Resolution: Not a Bug
  • ehcache-core
  • alexsnaps
  • Reporter: johannb
  • February 06, 2012
  • 0
  • Watchers: 3
  • July 27, 2012
  • February 10, 2012

Description

Any Groovy class will have a number of {{transient}} fields that should not be counted as they will not be serialized.

Here’s the javap output of an example class

public class freezer.entities.User extends java.lang.Object implements java.io.Externalizable,groovy.lang.GroovyObject{
    private java.lang.String name;
    private java.util.BitSet pageIndex;
    private long lastLogin;
    private boolean $print$names;
    private static org.codehaus.groovy.reflection.ClassInfo $staticClassInfo;
    public static transient boolean __$stMC;
    private transient groovy.lang.MetaClass metaClass;

{{ObjectGraphWalker}} will recursively try to calculate the size of the {{metaClass}} field. Unfortunately, there’s several MB of Groovy data behind it, which causes the size calculation (and saving) of the object to be aborted.

One possible fix is changing (in ObjectGraphWalker)

                if (!Modifier.isStatic(field.getModifiers()) &&
                        !field.getType().isPrimitive() &&
                        !field.getName().startsWith(TC_INTERNAL_FIELD_PREFIX)) {

to

                if (!Modifier.isStatic(field.getModifiers()) &&
                        !field.getType().isPrimitive() &&
                        !field.getName().startsWith(TC_INTERNAL_FIELD_PREFIX)
                        !Modifier.isTransient(field.getModifiers())) {

Comments

Alexander Snaps 2012-02-08

As I see it, there is no correlation between serialization behaviour and heap consumption. I don’t know enough about Groovy’s metaClass information to say this for sure, but it does feel as if you’d want to ignore groovy.lang.MetaClass instances from the measurement process. This can be achieved by annotating the Class with @IgnoreSizeOf, which might be an issue in this case. For these cases you can declare a “filter file” using the -Dnet.sf.ehcache.sizeof.filter system property to point to a file that has, one entry per line, FQCN to ignore. Alternatively you can ignore fields (FQCN.fieldName) or entire packages (like groovy.lang).

Johann Burkard 2012-02-08

Alex,

thanks for your comment but these fields are added by the Groovy compiler at compile time and it’s impossible (at least AFAIK YMMV HAND) to use annotations here.

You mention system properties… I appreciate being able to override some things via system properties as a last resort but if I decide to deploy an app into a running app server, I can’t change those and restarts are out of the question for people like me who run one frontend server and one app server.

Alexander Snaps 2012-02-08

I fear this might be really really ugly, but System.getProperties().put(“net.sf.ehcache.sizeof.filter”, url); would be a solution (if the security manager allows it). We haven’t yet provided an API to declare these filters or specific SizeOfEngine (as this is another option). But maybe that would be required. The problem with such filters is that implementors (such as the Groovy guys) might change these field names, classes, add or remove such as they want… It still is unclear what would be the best approach, other than having framework developer use the annotation (or using a non ehcache dependent way to annotate these fields).

Alexander Snaps 2012-02-10

This should be solved using a well defined public API for handling these special cases

Alexander Snaps 2012-02-10

This isn’t a bug, but rather a feature request. Created an associated JIRA for it