MappedClass leak with BasicDAO

35 views
Skip to first unread message

Mike L

unread,
Mar 1, 2012, 8:21:03 PM3/1/12
to mor...@googlegroups.com
I'm guessing I'm doing something dumb here because I've made it as simple as possible and still see a leak.

Setup:
  • Java 6
  • Tomcat 6
  • morphia-0.99.1-SNAPSHOT
  • mongo-2.7.2

Steps:

  • Create a servlet with a doGet that does nothing besides connect to a db and create an instance of a BasicDAO
  • Hit the servlet with a request that executes doGet
  • Run garbage collection
  • Check heap and see that there are 2 instances of MappedClass in the heap (expected 1 instance)
  • Hit the servlet again
  • Run garbage collection
  • Check heap and see that there are 3 instances of MappedClass in the heap (expected 1 instance)

Every time the doGet method is called, I get another instance of MappedClass which is indeed the class the DAO is for.  No other obvious classes are leaking (except the MappedFields that are part of the MappedClass) - one Mapper, one DatastoreImpl, one MongoManager (see below), no DAO or model classes.

I've run the same test without the DAO, just using my MongoManager to get the Datastore and using that directly to read the db.  That works fine - no leaks.

Here's some code:

public class TesterDao extends BasicDAO<Tester, ObjectId> {
   
    public TesterDao() {
        super(Tester.class, MongoManager.instance().getDb());
    }
}

public class MorphiaTestServlet extends HttpServlet {


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        TesterDao testerDao = new TesterDao();
    }
}

public class MongoManager {
   
    private static final MongoManager INSTANCE = new MongoManager();
   
    private final String MONGO_HOST = "localhost";
    private final int MONGO_PORT = 27017;
   
    private Datastore theDb = null;
   
    private MongoManager() {

        Mongo mongo;
        try {
            mongo = new Mongo(MONGO_HOST, MONGO_PORT);
            theDb = new Morphia()
                .map(Tester.class)
                .createDatastore(mongo, "MorphiaTest");
            theDb.ensureIndexes();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (MongoException e) {
            e.printStackTrace();
        }           
    }
   
    public static MongoManager instance() {
        return INSTANCE;
    }
   
    public Datastore getDb() {
        return theDb;
    }
}

@Entity (noClassnameStored=true)
public class Tester {

    @Id
    private ObjectId id;
   
    private String name;
   
    public Tester() {}
   
    public Tester(String name) {
        this.name = name;
    }
   
    public ObjectId getId() {
        return id;
    }
   
    public String getName() {
        return name;
    }
}

Mike L

unread,
Mar 2, 2012, 7:20:30 PM3/2/12
to mor...@googlegroups.com
I fixed up my more production like code w/ the following as a work-around and the leak goes away.  In all my DAO classes:
  • No longer extend BasicDAO
  • Use a reference to the Datastore to call createQuery(<T>) instead of just calling createQuery()
  • Add the methods I need that were provided by BasicDAO (like save)
All relatively trivial changes.  Still, I feel I must be doing something wrong w/ BasicDAO - the leak is rather extreme and would pop up in moments in any production system.

Scott Hernandez

unread,
Mar 2, 2012, 7:41:12 PM3/2/12
to mor...@googlegroups.com
Can you provide a code sample for this? I can try to run through it in
a profiler. Please create an issue here with the code :
http://code.google.com/p/morphia/issues

Mike L

unread,
Mar 2, 2012, 8:15:37 PM3/2/12
to mor...@googlegroups.com
Code sample is in the original post.

I created Issue 385 w/ the same.
Reply all
Reply to author
Forward
0 new messages