Re: 'java.lang.OutOfMemory' and 'Bad File descriptor'

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Thu Feb 10 2005 - 17:40:03 EST

  • Next message: Dov Rosenberg: "Cayenne: Is it thread safe as compared to EOF?"

    Hi Laila,

    Hmm, nothing indicates a memory leak in Cayenne here. This is without
    analyzing your PoolManager code... [BTW you can probably use commons DBCP
    for more advanced connection management - 1.2M2 supports this out of the
    box, in 1.1 you can use it via a container-provided DataSource].

    "Bad file descriptor" error doesn't point to Cayenne either. So what you
    can do it turn on Cayenne SQL logging and watch for any queries that
    return too many rows... Also what is your estimate of how many concurrent
    DataContexts exist in the application at any given moment? You need to
    make sure that any unused DataContexts are garbage collected (i.e. not
    referenced anywhere in the application).

    If you don't find anything suspicious, I guess the leak is elsewhere... Oh
    and make sure your JVM has enough memory to begin with - use -Xmx startup
    option to increase this from default 64M.

    Andrus

    > Hi,
    >
    > When running my application, i see "java.lang.OutOfMemory" and "Bad File
    > descriptor" appear in the log without other indications.
    >
    > The application run more threads and each thread creates his data
    > context, perform more select query like this below, and insert new
    > objects.
    > In some case i must force the connection close and for this reason I
    > have extended the PoolManager (see code below).
    > Also, I wrote a simple ExtendedType implementation for Oracle LONG
    > fields.
    >
    > Some suggestion? Where it can be the problem?
    >
    > Thanks
    > Laila
    >
    >
    > -------------------- Select Query example
    > --------------------------------
    >
    > private static SQLTemplate query = new SQLTemplate(RawNews.class,
    > "select 'true' from dual where exists(select 'true' from rawnws where
    > id_source=$source and msg_from='$url')",
    > true);
    >
    > params = new java.util.HashMap();
    > params.put("source", this.source().id());
    > params.put("url", anUrl);
    >
    > query.setFetchingDataRows(true);
    > result =
    > this.dataContext().performQuery(query.queryWithParameters(params));
    >
    > ---------------------- Pool Manager example
    > ------------------------------
    >
    > public class PoolManager extends
    > org.objectstyle.cayenne.conn.PoolManager {
    >
    > private final java.util.HashSet _candidates;
    > private final java.util.Hashtable _owners;
    > private boolean _criticalSession;
    >
    > public PoolManager(.....) throws java.sql.SQLException {
    > super(....);
    > _criticalSession = false;
    > _candidates = new java.util.HashSet();
    > _owners = new java.util.Hashtable();
    > }
    >
    > protected boolean criticalSession() {
    > return _criticalSession;
    > }
    >
    > protected synchronized void setCriticalSession(boolean aValue) {
    > _criticalSession = aValue;
    > if(!aValue) {
    > this.notifyAll();
    > }
    > }
    >
    > protected java.util.HashSet candidates() {
    > return _candidates;
    > }
    >
    > protected java.util.Hashtable owners() {
    > return _owners;
    > }
    >
    > public java.sql.Connection getConnection(java.lang.String userName,
    > java.lang.String password) throws java.sql.SQLException {
    > java.sql.Connection result;
    >
    > if(this.criticalSession()) {
    > try {
    > this.wait();
    > } catch (java.lang.Exception e) {}
    > }
    >
    > synchronized (this) {
    > this.candidates().add(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > try {
    > result = super.getConnection(userName, password);
    > this.owners().put(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()),
    > result);
    > } catch (java.sql.SQLException e) {
    > this.candidates().remove(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > throw e;
    > }
    > }
    >
    > return result;
    > }
    >
    > public synchronized void
    > connectionErrorOccurred(javax.sql.ConnectionEvent anEvent) {
    > super.connectionErrorOccurred(anEvent);
    > this.owners().remove(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > this.candidates().remove(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > }
    >
    > public synchronized void
    > connectionClosed(javax.sql.ConnectionEvent anEvent) {
    > super.connectionClosed(anEvent);
    > this.owners().remove(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > this.candidates().remove(new
    > java.lang.Integer(java.lang.Thread.currentThread().hashCode()));
    > }
    >
    > protected synchronized boolean
    > forceConnectionClose(java.lang.Integer anHashCode) throws
    > java.sql.SQLException {
    > boolean result;
    > java.sql.Connection connection;
    >
    > connection = (java.sql.Connection)this.owners().get(anHashCode);
    >
    > if (connection != null) {
    > connection.close();
    > this.owners().remove(anHashCode);
    > this.candidates().remove(anHashCode);
    > result = true;
    > } else if(this.candidates().contains(anHashCode)) {
    > result = false;
    > } else {
    > result = true;
    > }
    >
    > return result;
    > }
    > }
    >
    > ----------------- ExtendedType example
    > ------------------------------------------
    >
    > public class LongType extends
    > org.objectstyle.cayenne.access.types.DefaultType {
    >
    > ....
    >
    > public void setJdbcObject( java.sql.PreparedStatement st,
    > java.lang.Object val,
    > int pos,
    > int type,
    > int precision) throws java.lang.Exception
    > {
    > if (val != null) {
    > com.extrapola.cayenne.oracle.LongType longType;
    > java.io.StringReader in;
    >
    > longType = (com.extrapola.cayenne.oracle.LongType)val;
    >
    > in = new java.io.StringReader(longType.string());
    > st.setCharacterStream(pos, in, longType.string().length());
    >
    > } else {
    > super.setJdbcObject(st, val, pos, type, precision);
    > }
    > }
    > }



    This archive was generated by hypermail 2.0.0 : Thu Feb 10 2005 - 17:40:05 EST