Re: [OT] Serious memory leak

2007-06-25 Thread Balazs Michnay
I was wondering about one more thing...
Somewhere I read that the GC can only collect objects that were instantiated 
with the new keyword.
Does it mean the the following two String creations differ when it comes to 
garbage collection?

1) String myString = This is my string;
2) String myString = new String(This is my string);

If the second one can only be garbage collected, this would explain my 
uncollectable char[] objects, because mostly I simply use the 1) version.
If you say this really does count when it comes to garbage collection, I'd 
rewrite my code and see what happens.

Thanks a lot,

  MB.

- Original Message 
From: Christopher Schultz [EMAIL PROTECTED]
To: Struts Users Mailing List user@struts.apache.org
Sent: Wednesday, June 20, 2007 2:29:29 PM
Subject: Re: [OT] Serious memory leak

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

Balazs Michnay wrote:
 Thanks a lot, these changes really did help, now MySQL reports that
 only one connection is used all over the website. I really do
 appreciate your help.

No problem. Another good tip is to set your connection pool size to 1
when working in development (and maybe even test). This will allow your
connection pool to be exhausted any time there is a potential for
deadlock (from the cp, that is).

Good luck,
- -chris

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGeR2o9CaO5/Lv0PARAspgAJ4yMYS06yOQ5CLE29ezyf1D5oaLhQCfWXuu
GHdfh1DPw+q/1WXEByma8L4=
=8bHg
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]








 

The fish are biting. 
Get more visitors on your site using Yahoo! Search Marketing.
http://searchmarketing.yahoo.com/arp/sponsoredsearch_v2.php

Re: [OT] Serious memory leak

2007-06-25 Thread Balazs Michnay
I was wondering about one more thing...
Somewhere I read that the GC can only collect objects that were instantiated 
with the new keyword.
Does it mean the the following two String creations differ when it comes to 
garbage collection?

1) String myString = This is my string;
2) String myString = new String(This is my string);

If
the second one can only be garbage collected, this would explain my
uncollectable char[] objects, because mostly I simply use the 1)
version.
If you say this really does count when it comes to garbage collection, I'd 
rewrite my code and see what happens.

Thanks a lot,

  MB.

- Original Message 
From: Christopher Schultz [EMAIL PROTECTED]
To: Struts Users Mailing List user@struts.apache.org
Sent: Wednesday, June 20, 2007 2:29:29 PM
Subject: Re: [OT] Serious memory leak

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

Balazs Michnay wrote:
 Thanks a lot, these changes really did help, now MySQL reports that
 only one connection is used all over the website. I really do
 appreciate your help.

No problem. Another good tip is to set your connection pool size to 1
when working in development (and maybe even test). This will allow your
connection pool to be exhausted any time there is a potential for
deadlock (from the cp, that is).

Good luck,
- -chris

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGeR2o9CaO5/Lv0PARAspgAJ4yMYS06yOQ5CLE29ezyf1D5oaLhQCfWXuu
GHdfh1DPw+q/1WXEByma8L4=
=8bHg
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



   
Ready
 for the edge of your seat? 
Check out tonight's top picks on Yahoo! TV. 
http://tv.yahoo.com/

Re: [OT] Serious memory leak

2007-06-25 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

Balazs Michnay wrote:
 Somewhere I read that the GC can only collect objects that were 
 instantiated with the new keyword.

That's an odd way of putting it. The garbage collector only works with
the heap. Since in Java nearly everything is on the heap (or, rather, it
appears that everything is on the heap, which is all you really need to
know), the garbage collector basically cleans up everything.

 Does it mean the the following two String creations differ when it
 comes to garbage collection?
 
 1) String myString = This is my string;
 2) String myString = new String(This is my string);
 
 If the second one can only be garbage collected, this would explain
 my uncollectable char[] objects, because mostly I simply use the 1)
 version.
 
 If you say this really does count when it comes to garbage
 collection, I'd rewrite my code and see what happens.

Well, you're introduced an odd concept into the discussion: the Java
class file constant pool. When you compile a string into a class file
(in this case, This is my string), the compiler puts the UTF-8
representation of it into a part of the class file itself. When line 1
of your code executes, no constructor is called... the java bytecode
primitive ldc (load constant) is called which returns the String
object directly.

In the case of line #2, a new String object is allocated, the constant
is loaded, and then the constructor String.init(String) is called.

You can see this yourself by compiling this simple class and then
decompiling it:

$ cat StringTest.java

public class StringTest
{
public void s1()
{
String s1 = This is a String;
}
public void s2()
{
String s2 = new String(This is a String);
}
}

$ javac StringTest.java
$ javap -c StringTest
Compiled from StringTest.java
public class StringTest extends java.lang.Object{
public StringTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object.init:()V
   4:   return

public void s1();
  Code:
   0:   ldc #2; //String This is a String
   2:   astore_1
   3:   return

public void s2();
  Code:
   0:   new #3; //class java/lang/String
   3:   dup
   4:   ldc #2; //String This is a String
   6:   invokespecial   #4; //Method
java/lang/String.init:(Ljava/lang/String;)V
   9:   astore_1
   10:  return

}

In the examples you have given, I'm not entirely sure what the role of
the GC is when it comes to constants loaded from the constant pool. The
class file format contains only the UTF-8 representation of the String,
so at some point a String object /must/ be constructed in memory. You'd
have to do some more research into the JVM specification to see how
constant Strings are handled.

You probably shouldn't have lots of string constants that contain a
/lot/ of text. Maybe 400 characters or so ought to be fine (say, a
semi-complex SQL query), but if you are talking about tons of text, you
might want to read that kind of thing out of a file.

Hope that helps,
- -chris
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGf73U9CaO5/Lv0PARAvsGAJ97ZDUpN4bhtfjE1w+/sm8tNxYp6gCgtxGt
CCIkTDuPsGGgMFmYfnh5nz0=
=DdN4
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [OT] Serious memory leak

2007-06-20 Thread Balazs Michnay
Chris,

Thanks a lot, these changes really did help, now MySQL reports that only one 
connection is used all over the website.
I really do appreciate your help.

Regards,

  MB

- Original Message 
From: Christopher Schultz [EMAIL PROTECTED]
To: Struts Users Mailing List user@struts.apache.org
Sent: Tuesday, June 19, 2007 7:10:49 PM
Subject: Re: [OT] Serious memory leak

Balazs,

Balazs Michnay wrote:
 recently I found
 out that my memory consumption of my
 application is nothing compared to the memory consumption of my database
 server (MySQL).

 I'm theoretically using connection pool to save resources of my
 database server, but each time I make a query, I have a brand new
 connection.

Well... are you /theoretically/ or /actually/ using a JDBC connection pool?

 Why doesn't PID 11 use the connection used by PID 10?

 There might be
 some errors in my code, however, it was previously
 reviewed and said to be correct.

Do you trust the reviewer? Looking at the code you posted, I would not
trust them any more :(

 private Statement getConnectionStatement(Connection conn) throws Exception {
 
 Context ctx = new InitialContext();
 if(ctx == null )
 throw new Exception(Boom - No Context);
 
 Context envCtx = (Context) ctx.lookup(java:comp/env);
 DataSource ds = (DataSource) envCtx.lookup(jdbc/akr_db);
 
 if (ds != null) {
 
 conn = ds.getConnection();
 if(conn == null) throw new Exception();
 
 } else throw new Exception();
 
 return conn.createStatement();
 }

Do you pass an active connection to this method? If you do, then you are
leaking connections every time you try to create a statement. If you are
always passing null, then why do you have the Connection parameter to
this method?

A proper method with the above signature should be implemented like this:

private Statement getConnectionStatement(Connection conn)
{
return conn.createStatement();
}

As you can see, this method is completely worthless. It looks like your
method ought to be this instead:

private Connection getConnection()
{
 Context ctx = new InitialContext();
 if(ctx == null )
 throw new Exception(Boom - No Context);

 Context envCtx = (Context) ctx.lookup(java:comp/env);

// Consider checking envCtx against null, here, too

// Consider making the JNDI resource name configurable
// instead of hard-coding.
 DataSource ds = (DataSource) envCtx.lookup(jdbc/akr_db);

 if (ds != null) {

 conn = ds.getConnection();
 if(conn == null) throw new Exception();

 } else throw new Exception();

return conn;
}

The closeConnection method looks fine except for these style comments:

1. Call this method close... it closes much more than the connection.
2. Don't swallow the SQLExceptions. At least log them, but never
   swallow an exception!
3. Don't bother setting each reference to null. This is a waste of time,
   and clutters the code.

Selected lines from your code:

 Connection conn = null;
 try {
 stmt = getConnectionStatement(conn);

// Note that conn is still null here.

 } catch (Exception e) {
 System.err.println(e.getMessage());
 } finally {
 closeConnection(conn,stmt,rst);
 }

Conn is still null, so it will never be closed.

YOU ARE LEAKING CONNECTIONS. FIX YOUR CODE.

It should look like this:

Connection conn = null;
Statement stmt = null;  // Or PreparedStatement if needed
ResultSet rst = null;

String query = SELECT * FROM MyTable;

try {
conn = getConnection();
stmt = conn.createStatement();
rst = stmt.executeQuery(query);

// YOU SHOULD CHECK THIS FOR false:
rst.next();

this.setTartam(rst.getString(tartam));

} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
closeConnection(conn,stmt,rst);
}

Note that PreparedStatements are universally better than bare Statements
when using parameterized queries (which you are not using, here).

These changes should help A LOT. You are probably leaking connections
all over the place. I'm curious as to why you aren't getting messages on
stderr that your connection pool is empty...

-chris









   

Building a website is a piece of cake. Yahoo! Small Business gives you all the 
tools to get online.
http://smallbusiness.yahoo.com/webhosting 

Re: [OT] Serious memory leak

2007-06-20 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

Balazs Michnay wrote:
 Thanks a lot, these changes really did help, now MySQL reports that
 only one connection is used all over the website. I really do
 appreciate your help.

No problem. Another good tip is to set your connection pool size to 1
when working in development (and maybe even test). This will allow your
connection pool to be exhausted any time there is a potential for
deadlock (from the cp, that is).

Good luck,
- -chris

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGeR2o9CaO5/Lv0PARAspgAJ4yMYS06yOQ5CLE29ezyf1D5oaLhQCfWXuu
GHdfh1DPw+q/1WXEByma8L4=
=8bHg
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [OT] Serious memory leak

2007-06-19 Thread Balazs Michnay
 user@struts.apache.org
Sent: Wednesday, May 30, 2007 5:45:11 PM
Subject: Re: [OT] Serious memory leak

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

I just realized that we're talking about approximately 1MB of char[]
data... what's the big deal about that? ;)

Balazs Michnay wrote:
 Can you expand the + next to Arrays.copyOfRange to see what the rest
 of the stack trace is? I'm sure that a lot of things call
 Arrays.copyOfRange, so it's hard to determine what the problem is. Post
 another screenshot if you can.
 
 Sure,
  here it is (profiler3_expanded.JPG):
 http://www.inf.u-szeged.hu/~michnay/profiler/
 As you can see, now there are other methods as well allocating char[] objects.
 It's pretty confusing and very hard to track how exactly my pages are 
 processed by the server... at least, it is for me... :)

It looks like most of those char[] objects are being allocated by Sun's
HTTP client. What are you loading over HTTP? Class files? Apparently,
you have some big arrays lying around:

 2 * 16k bytes allocated by HttpClient.parseHTTP
39 * 16k bytes allocated by HttpClient.init (the constructor)

These look like buffers. I'd be interested in seeing what is using
HttpClient in your code (or Struts, I suppose).

The other section (copyOfRange) has created lots of String objects. Some
of them are obvious: you are reading properties from properties files
and they take up memory. StringBuilder is often used by the compiler to
assemble Strings combined using the + operator (for Strings). You can
use it yourself, too, just like a StringBuffer. Somewhere, strings are
being created (which, of course, are made-up almost entirely of char[]
objects).

 I'll
 try to factor out the JNDI parts. Should I factor out the creation of
 statement and result objects as well, or only the connection should be
 factored out?

I would only do the Connection. What else would you do? Have a method
like this?

public Statement createStatement(Connection conn, String sql)
{
return conn.createStatement(sql);
}

??! That's a pretty worthless method.

 Should I create another method to free up the resources?

I have done that myself:

protected void close(Connection conn, Statement s, ResultSet r)
{
 /// this guy is protected because it's in a superclass

 // for each object, check for null, try { close } catch { log }
}

 In terms of design, I would write that method to return a List of
 application-specific objects instead of maintaining two separate
 (untyped) lists that just happen to be related. It is a much more
 understandable design and yields much more readable code. It will also
 simplify your JSP loop, etc.
 
 What do you mean by List of application-specific objects? Is it a
 multi-dimensional ArrayList object? I'm very interested in creating
 well-readable and well-understandable code, so some samples would be
 appreciated :) (sorry, I'm not very experienced in Java)

I know how you feel. We used to have a programmer who didn't realize he
could create his own types. Stop thinking that everything has to be a
String hidden inside a baffling maze of nested Lists and Maps. If you
have an entity that you like to think of as a person (for example),
then you can represent this data in at least two ways:

1. Use a List of Strings where the index of the string has meaning,
   but only in your head. Something like this:

   ArrayList person = new ArrayList();
   person.add(Chris);   // 0 == first name
   person.add(Schultz); // 1 == last name
   person.add(Male);// 2 == gender

   ArrayList people = new ArrayList();
   people.add(person);
   // etc.

2. Use an object you define yourself.

   public class Person
   {
  String firstName;
  String lastName;
   }

   ArrayList people = new ArrayList();
   people.add(new Person(Chris, Schultz, Male));
   // etc.

If you use solution #1, you'll never know if the ArrayList you're
getting is an array of String representing person entities or a list
of strings representing Account entities, or whatever. You basically
have to cross your fingers and hope that the documentation for the
method is correct.

If you use #2, you can use the compiler and runtime to enforce your
notion of what is what: That list /does/ contain Person objects. You
seriously simplify your code and rarely get confused. You save a lot of
memory, too, since ArrayLists have overhead that you don't need if you
use your own objects.

These things are typically called business objects, but only when they
map into domain-specific entities (meaning that they represent real
concepts in the language of the problem... like Account for financial
software, or PurchaseOrder for an ordering system).

You are free to create other types that are useful to you even if they
are not business objects per se any time you find yourself
stuffing things like bare Strings into Maps or Lists, ask yourself if
you shouldn't be defining your own type (or class... or object... or
whatever you want to call it).

 Do you see

Re: [OT] Serious memory leak

2007-06-19 Thread Balazs Michnay
I forgot to include the link to the image. Here it is:

http://www.inf.u-szeged.hu/~michnay/db/db_connections.jpg

- Original Message 
From: Balazs Michnay [EMAIL PROTECTED]
To: Struts Users Mailing List user@struts.apache.org
Sent: Tuesday, June 19, 2007 2:16:06 PM
Subject: Re: [OT] Serious memory leak

Thanks for your reply on the memory leak issue
Well, recently I found out that my memory consumption of my application is 
nothing compared to the memory consumption of my database server (MySQL).
I'm theoretically using connection pool to save resources of my database 
server, but each time I make a query, I have a brand new connection.
Please take a look at the following image that shows the state of my user 
connection.
I have lots of connections, however theses are only different queries from the 
same web application.
Why doesn't PID 11 use the connection used by PID 10?
There might be some errors in my code, however, it was previously reviewed and 
said to be correct.
Please take a look at the following source...
I have 2 methods related to my connection pool:

---GETTING CONNECTION 
---
private Statement getConnectionStatement(Connection conn) throws Exception {

Context ctx = new InitialContext();
if(ctx == null )
throw new Exception(Boom - No Context);

Context envCtx = (Context) ctx.lookup(java:comp/env);
DataSource ds = (DataSource) envCtx.lookup(jdbc/akr_db);

if (ds != null) {

conn = ds.getConnection();
if(conn == null) throw new Exception();

} else throw new Exception();

return conn.createStatement();
}
-
---CLOSING CONNECTION 
---

private void closeConnection(Connection conn, Statement stmt, ResultSet rst) {
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
stmt = null;
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
conn = null;
}
if (rst != null) {
try { rst.close(); } catch (SQLException e) { ; }
rst = null;
}
}
-
---USING CONNECTION POOL IN A 
METHOD-

Connection conn = null;
Statement stmt = null;  // Or PreparedStatement if needed
ResultSet rst = null;

String query = SELECT * FROM MyTable;

try {
stmt = getConnectionStatement(conn);
rst = stmt.executeQuery(query);

rst.next();

this.setTartam(rst.getString(tartam));

} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
closeConnection(conn,stmt,rst);
}
-

Furthermore, I have a context.xml with the following content:

Context path=/SZTGKR
  ResourceLink global=jdbc/akr_db name=jdbc/akr_db 
type=javax.sql.DataSource/
/Context

-
In the web.xml I have an entry related to my db connection:

 resource-ref
description DB Connection Pooling/description
res-ref-name jdbc/akr_db/res-ref-name
res-type javax.sql.DataSource/res-type
res-auth Container/res-auth
/resource-ref   
--
GlobalNamingResources
Environment
  name=simpleValue
  type=java.lang.Integer
  value=30/
Resource
  auth=Container
  name=jdbc/akr_db
  type=javax.sql.DataSource
  maxActive=100
  maxIdle=30
  username=balazs
  maxWait=1
  driverClassName=com.mysql.jdbc.Driver
  removeAbandoned=true
  password=12345
  url=jdbc:mysql://localhost:3306/akr_db
  removeAbandonedTimeout=30/
Resource
  auth=Container
  description=User database that can be updated and saved
  name=UserDatabase
  type=org.apache.catalina.UserDatabase
  pathname=conf/tomcat-users.xml
  factory=org.apache.catalina.users.MemoryUserDatabaseFactory/
  /GlobalNamingResources

Re: [OT] Serious memory leak

2007-06-19 Thread Christopher Schultz
Balazs,

Balazs Michnay wrote:
 recently I found
 out that my memory consumption of my
 application is nothing compared to the memory consumption of my database
 server (MySQL).

 I'm theoretically using connection pool to save resources of my
 database server, but each time I make a query, I have a brand new
 connection.

Well... are you /theoretically/ or /actually/ using a JDBC connection pool?

 Why doesn't PID 11 use the connection used by PID 10?

 There might be
 some errors in my code, however, it was previously
 reviewed and said to be correct.

Do you trust the reviewer? Looking at the code you posted, I would not
trust them any more :(

 private Statement getConnectionStatement(Connection conn) throws Exception {
 
 Context ctx = new InitialContext();
 if(ctx == null )
 throw new Exception(Boom - No Context);
 
 Context envCtx = (Context) ctx.lookup(java:comp/env);
 DataSource ds = (DataSource) envCtx.lookup(jdbc/akr_db);
 
 if (ds != null) {
 
 conn = ds.getConnection();
 if(conn == null) throw new Exception();
 
 } else throw new Exception();
 
 return conn.createStatement();
 }

Do you pass an active connection to this method? If you do, then you are
leaking connections every time you try to create a statement. If you are
always passing null, then why do you have the Connection parameter to
this method?

A proper method with the above signature should be implemented like this:

private Statement getConnectionStatement(Connection conn)
{
return conn.createStatement();
}

As you can see, this method is completely worthless. It looks like your
method ought to be this instead:

private Connection getConnection()
{
 Context ctx = new InitialContext();
 if(ctx == null )
 throw new Exception(Boom - No Context);

 Context envCtx = (Context) ctx.lookup(java:comp/env);

// Consider checking envCtx against null, here, too

// Consider making the JNDI resource name configurable
// instead of hard-coding.
 DataSource ds = (DataSource) envCtx.lookup(jdbc/akr_db);

 if (ds != null) {

 conn = ds.getConnection();
 if(conn == null) throw new Exception();

 } else throw new Exception();

return conn;
}

The closeConnection method looks fine except for these style comments:

1. Call this method close... it closes much more than the connection.
2. Don't swallow the SQLExceptions. At least log them, but never
   swallow an exception!
3. Don't bother setting each reference to null. This is a waste of time,
   and clutters the code.

Selected lines from your code:

 Connection conn = null;
 try {
 stmt = getConnectionStatement(conn);

// Note that conn is still null here.

 } catch (Exception e) {
 System.err.println(e.getMessage());
 } finally {
 closeConnection(conn,stmt,rst);
 }

Conn is still null, so it will never be closed.

YOU ARE LEAKING CONNECTIONS. FIX YOUR CODE.

It should look like this:

Connection conn = null;
Statement stmt = null;  // Or PreparedStatement if needed
ResultSet rst = null;

String query = SELECT * FROM MyTable;

try {
conn = getConnection();
stmt = conn.createStatement();
rst = stmt.executeQuery(query);

// YOU SHOULD CHECK THIS FOR false:
rst.next();

this.setTartam(rst.getString(tartam));

} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
closeConnection(conn,stmt,rst);
}

Note that PreparedStatements are universally better than bare Statements
when using parameterized queries (which you are not using, here).

These changes should help A LOT. You are probably leaking connections
all over the place. I'm curious as to why you aren't getting messages on
stderr that your connection pool is empty...

-chris




signature.asc
Description: OpenPGP digital signature


Re: [OT] Serious memory leak

2007-05-30 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Balazs,

I just realized that we're talking about approximately 1MB of char[]
data... what's the big deal about that? ;)

Balazs Michnay wrote:
 Can you expand the + next to Arrays.copyOfRange to see what the rest
 of the stack trace is? I'm sure that a lot of things call
 Arrays.copyOfRange, so it's hard to determine what the problem is. Post
 another screenshot if you can.
 
 Sure,
  here it is (profiler3_expanded.JPG):
 http://www.inf.u-szeged.hu/~michnay/profiler/
 As you can see, now there are other methods as well allocating char[] objects.
 It's pretty confusing and very hard to track how exactly my pages are 
 processed by the server... at least, it is for me... :)

It looks like most of those char[] objects are being allocated by Sun's
HTTP client. What are you loading over HTTP? Class files? Apparently,
you have some big arrays lying around:

 2 * 16k bytes allocated by HttpClient.parseHTTP
39 * 16k bytes allocated by HttpClient.init (the constructor)

These look like buffers. I'd be interested in seeing what is using
HttpClient in your code (or Struts, I suppose).

The other section (copyOfRange) has created lots of String objects. Some
of them are obvious: you are reading properties from properties files
and they take up memory. StringBuilder is often used by the compiler to
assemble Strings combined using the + operator (for Strings). You can
use it yourself, too, just like a StringBuffer. Somewhere, strings are
being created (which, of course, are made-up almost entirely of char[]
objects).

 I'll
 try to factor out the JNDI parts. Should I factor out the creation of
 statement and result objects as well, or only the connection should be
 factored out?

I would only do the Connection. What else would you do? Have a method
like this?

public Statement createStatement(Connection conn, String sql)
{
return conn.createStatement(sql);
}

??! That's a pretty worthless method.

 Should I create another method to free up the resources?

I have done that myself:

protected void close(Connection conn, Statement s, ResultSet r)
{
 /// this guy is protected because it's in a superclass

 // for each object, check for null, try { close } catch { log }
}

 In terms of design, I would write that method to return a List of
 application-specific objects instead of maintaining two separate
 (untyped) lists that just happen to be related. It is a much more
 understandable design and yields much more readable code. It will also
 simplify your JSP loop, etc.
 
 What do you mean by List of application-specific objects? Is it a
 multi-dimensional ArrayList object? I'm very interested in creating
 well-readable and well-understandable code, so some samples would be
 appreciated :) (sorry, I'm not very experienced in Java)

I know how you feel. We used to have a programmer who didn't realize he
could create his own types. Stop thinking that everything has to be a
String hidden inside a baffling maze of nested Lists and Maps. If you
have an entity that you like to think of as a person (for example),
then you can represent this data in at least two ways:

1. Use a List of Strings where the index of the string has meaning,
   but only in your head. Something like this:

   ArrayList person = new ArrayList();
   person.add(Chris);   // 0 == first name
   person.add(Schultz); // 1 == last name
   person.add(Male);// 2 == gender

   ArrayList people = new ArrayList();
   people.add(person);
   // etc.

2. Use an object you define yourself.

   public class Person
   {
  String firstName;
  String lastName;
   }

   ArrayList people = new ArrayList();
   people.add(new Person(Chris, Schultz, Male));
   // etc.

If you use solution #1, you'll never know if the ArrayList you're
getting is an array of String representing person entities or a list
of strings representing Account entities, or whatever. You basically
have to cross your fingers and hope that the documentation for the
method is correct.

If you use #2, you can use the compiler and runtime to enforce your
notion of what is what: That list /does/ contain Person objects. You
seriously simplify your code and rarely get confused. You save a lot of
memory, too, since ArrayLists have overhead that you don't need if you
use your own objects.

These things are typically called business objects, but only when they
map into domain-specific entities (meaning that they represent real
concepts in the language of the problem... like Account for financial
software, or PurchaseOrder for an ordering system).

You are free to create other types that are useful to you even if they
are not business objects per se any time you find yourself
stuffing things like bare Strings into Maps or Lists, ask yourself if
you shouldn't be defining your own type (or class... or object... or
whatever you want to call it).

 Do you see any place where objects could not be freed-up? Where?
 
 I'll show you. Please take a look at
  

Re: [OT] Serious memory leak

2007-05-30 Thread David Durham, Jr.

Maybe you're creating a new session with each request.

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]