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