This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: maximum memory for gcj-compiled executable?
On Fri, 2003-04-04 at 13:44, Lars Andersen wrote:
> Ranjit Mathew wrote:
> >>I have made this simple program that reads a web page, and then does
> >>nothing with it ;)
> >>
> >>Compile it under win32/mingw using Mohan's latest GCC3.3
> >>
> >>Run it.
> >>
> >>The heap soon stabilizes and stays put (about 1000KB)
> >>
> >>Now open the task manager and watch memory usage slowly grow and grow
> >>and grow....
> >
> >
> > Yes, I see this behaviour too. Even after statically allocating
> > "buf" and "output" (and remembering to output.setLength( 0) at the
> > start of read( )) and explicitly closing streams and connections
> > and even omitting the creation of the intermediate strings...i.e.
> > the mere act of reading is causing this increase!
> >
> > Don't know what's causing it and I wouldn't venture a guess
> > either. :-(
> >
> > Ranjit.
>
>
> Just tried it reading a file instead of reading a web page.
> This did not exhibit any growing mem usage.
>
> This is likely a problem in java.net / mingw
I tried modifying TestThread.java (see it in
http://gcc.gnu.org/ml/java/2003-04/msg00054.html ), to write and read
directly to java.net.Socket instead of using java.net.HttpURLConnection.
With this change the memory leak disappears.
Maybe this is a clue to where the bug is.
Please note that this way of conducting a http request is much, MUCH
slower than using java.net.HttpURLConnection, so it takes a while for it
to stabilize...
Here is how the new performRequest() reads :
....
public void performRequest()
{
String uri = "/index.html";
String host = "www.apache.org";
int port = 80;
SocketURL surl = new SocketURL(host);
surl.setPort( port );
surl.setMethod("GET");
surl.setHeader("Host",""+host+":"+port);
surl.connectSocket();
java.io.DataInputStream dis = surl.getData(uri,null);
String res = surl.readDataInputStream(dis);
System.out.println("Length of page="+res.length() );
}
....
Attached:
SocketURL.java
TestThread.java
/Lars Andersen
/*
* TestThread.java
*
* Created on April 3, 2003, 3:16 PM
*/
import java.io.*;
import java.util.*;
import java.net.*;
/**
*
* @author lars
*/
public class TestThread extends Thread
{
/** Creates a new instance of TestThread */
public TestThread()
{
}
public void run()
{
while (true)
{
long sleep = 3000;
try
{
System.out.println("\n");
Thread.sleep(600);
performRequest();
Thread.sleep(200);
performRequest();
Thread.sleep(200);
performRequest();
Thread.sleep(200);
performRequest();
long total = Runtime.getRuntime().totalMemory() / 1024;
long free = Runtime.getRuntime().freeMemory() / 1024;
System.out.println("Heap Size "+total);
System.out.println("Free Heap Size "+free);
}
catch (InterruptedException ex) {} // ignore exception!
}
}
public void performRequest()
{
String uri = "/index.html";
String host = "www.apache.org";
int port = 80;
SocketURL surl = new SocketURL(host);
surl.setPort( port );
surl.setMethod("GET");
surl.setHeader("Host",""+host+":"+port);
surl.connectSocket();
java.io.DataInputStream dis = surl.getData(uri,null);
String res = surl.readDataInputStream(dis);
System.out.println("Length of page="+res.length() );
/*try
{
String uri = "/index.html";
java.net.URL url = new java.net.URL("http://www.apache.org"+uri);
java.net.HttpURLConnection uc = (java.net.HttpURLConnection) url.openConnection();
uc.setRequestMethod("GET");
uc.connect();
java.io.InputStream is = uc.getInputStream();
String res = read(is);
System.out.println("*Length of page="+res.length() );
}
catch (Exception e)
{
e.printStackTrace(System.out);
}*/
}
public String read(InputStream is)
{
StringBuffer output = new StringBuffer();
try
{
byte[] buf = new byte[1000];
int res=0;
res = is.read(buf);
while(res>0)
{
String s = new String(buf);
s = s.substring(0,res);
output.append( s );
res = is.read(buf);
}
is.close();
}
catch(IOException exc)
{
exc.printStackTrace(System.out);
}
return output.toString();
}
public static void main(String[] args)
{
System.out.println("Starting TestThread app");
try
{
TestThread tt = new TestThread();
tt.start();
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
}
}
import java.net.*;
import java.io.*;
import java.util.*;
public class SocketURL extends Object
{
StringBuffer headers = new StringBuffer();
Socket sock = null;
String host = "";
int port = 80;
String method = "GET";
String version = "1.1";
/** Creates new SocketURL */
public SocketURL(String host)
{
this.host = host;
}
public void setPort(int p) { port = p; }
public void setHost(String h) { host = h; }
public void setVersion(String v) { version = v; }
public void setMethod(String m) { this.method = m; }
public void setHeader(String key, String value)
{
headers.append(key+": "+value+"\r\n");
}
public void connectSocket()
{
int numTries = 0;
boolean connectOk = false;
while (!connectOk && numTries++ < 3)
{
try
{
sock = new Socket(host, port);
connectOk = true;
}
catch (Exception ex)
{
try { Thread.sleep(20); } catch (InterruptedException iEx) {}
}
}
}
public DataInputStream getData(String path, String request)
{
try
{
StringBuffer out = new StringBuffer();
//System.out.println("2");
DataInputStream inStream = new DataInputStream(sock.getInputStream());
DataOutputStream outStream = new DataOutputStream(sock.getOutputStream());
outStream.writeBytes(method+" "+path+" HTTP/"+version+"\r\n");
out.append(method+" "+path+" HTTP/"+version+"\r\n");
outStream.writeBytes(headers.toString());
out.append(headers.toString());
// Send a \r\n to indicate the end of the header
outStream.writeBytes("\r\n");
out.append("\r\n");
// Now send the information you are posting
if (request!=null)
{
outStream.writeBytes(request+ "\r\n");
out.append(request+ "\r\n");
}
return inStream;
}
catch (Exception e)
{
}
return null;
}
public String readDataInputStream(DataInputStream dis)
{
StringBuffer output = new StringBuffer();
try
{
byte[] buf = new byte[1000];
int res=0;
res = dis.read(buf);
while(res>0)
{
String s = new String(buf);
s = s.substring(0,res);
output.append( s );
res = dis.read(buf);
}
dis.close();
}
catch(IOException exc)
{
}
return ""+output;
}
}