Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2005

Tip: Looking for answers? Try searching our database.

URLConnection "memory leak"

Thread view: 
timjowers@gmail.com - 03 Jun 2005 05:51 GMT
URLConnection leaks memory and after a while will return the memory. No
amount of calling System.gc(); will clean it up. OK for small apps but
I am writing one that downloads 100 or so pages synchronously. OK
unless I experience several clients asking my server to do this at
once. Then Java gives the almost useless OutOfMemoryError. So much for
Garbage Collection. At this point GC just means random
non-deterministic memory management and means, unlike in C++, I cannot
achieve a robust server application. How can Java justify giving
OutOfMemoryError when NO REFERENCES ARE HELD IN MY PROGRAM!!!! I guess
URLConnection must have some internal static buggy code.

Any ideas how to get URLConnection to stop hanging onto memory?

Here's some test code below.

TimJowers

/**
* Sample memory
*/
import java.net.*;
import java.io.*;
import java.util.*;
import java.security.*;

public class Leaky {

    public String strXML = null;
    private String proxyHost=null, proxyPort=null, username=null,
password=null,
        httpRequest=null, base64Encoded=null, proxyType="2",
        formValues=null, formMethod="", optionFile=null;
    private URL url=null;
    private URLConnection urlConnection=null;
    private InputStream is=null;
    private File file=null;
    private FileOutputStream out=null;
    private int ftpPort=21;
    private boolean notAssigned = true,
        ftpTrue=false, ftpPassive=false, ftpAscii=false,
        https=false, nonverbose=true, post=false, booleanOptionFile=false;
    private StringBuffer sbuf = null;
    private byte[] bytesRead = new byte[4096];

    protected void zeroMem()
    {
        strXML = null;
        proxyHost=null; proxyPort=null; username=null; password=null;
        httpRequest=null; base64Encoded=null;
        formValues=null;
        formMethod=""; optionFile=null;
        url=null;
        urlConnection=null;
        is=null;
        file=null;
        out=null;
        sbuf = null;
        bytesRead = null;
    }

    public URLConnection setupProxy ( String [] args ) throws Exception
 {
        getOptions(args);

        if (https) {
            if (!nonverbose) {
                System.out.println("Using https communication");
            }
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            System.setProperty("http.keepAlive", "false");
            System.setProperty( "java.protocol.handler.pkgs",
                              "com.sun.net.ssl.internal.www.protocol" );
        }
        if (formMethod != null && formMethod.equalsIgnoreCase("get")) {
            httpRequest = httpRequest + "?" + encodeHttpString(formValues);
        }
        try {
            url = new URL(httpRequest);
        } catch (MalformedURLException e) {
            if (!nonverbose) {
                System.err.println("Malformed URL, must be
http://somehost[/file]");
            } else {
                throw new Exception("Malformed URL, must be
http://somehost[/file]");
            }
            return null;
        }
        if (proxyHost != null) {
            if (proxyType.equals("1") || proxyType.equals("3")) {
                System.getProperties().put( "proxySet", "true" );
                System.getProperties().put( "proxyHost", proxyHost);
                System.getProperties().put( "proxyPort", proxyPort);
            } else {
                if (proxyType.equals("4")) {
                    System.getProperties().put( "socksProxySet", "true");
                    System.getProperties().put( "socksProxyHost", proxyHost);
                    System.getProperties().put( "SocksProxyPort" , proxyPort);
                } else {
                    if (proxyType.equals("5")) {
                        System.getProperties().put( "ftpProxySet", "true" );
                        System.getProperties().put( "ftpProxyHost", proxyHost );
                        System.getProperties().put( "ftpProxyPort", proxyPort );
                    } else {
                        System.getProperties().put("firewallSet", "true");
                        System.getProperties().put("firewallHost", proxyHost);
                        System.getProperties().put("firewallPort", proxyPort);
                        System.getProperties().put("http.proxyHost", proxyHost);
                        System.getProperties().put("http.proxyPort", proxyPort);
                    }}}
            if (https && proxyHost != null) {
                System.getProperties().put("https.proxyHost", proxyHost);
                System.getProperties().put("https.proxyPort", proxyPort);
            }
        }
        try {
            urlConnection = url.openConnection();
        } catch (IOException e) {
            if (!nonverbose) {
                System.err.println("Error opening URL connection to " +
httpRequest);
            } else {
                throw new Exception("Error opening URL Connection to " +
httpRequest);
            }
            return null;
        }
        if (proxyHost != null) {
            Base64 base64 = new Base64(username + ":" + password);
            base64.encode();
            base64Encoded = "Basic " + base64.getOutgoing();
            urlConnection.setRequestProperty("Proxy-Connection","Keep-Alive");
            if (proxyType.equals("3")) {
                urlConnection.setRequestProperty("Authorization",
                                                base64Encoded);
            } else {
                urlConnection.setRequestProperty("Proxy-Authorization",
                                                base64Encoded);
            }
        }
        return urlConnection;
 }

    public boolean doWget ( String args ) throws Exception {
     // if args are all on one string then break into an array of strings
     StringTokenizer strTok = new StringTokenizer( args );
     String []argv = new String[ strTok.countTokens() ];
     for(int i=0; strTok.hasMoreTokens(); i++ )
        argv[i] = strTok.nextToken();
     return doWget( argv );
    }

    public boolean doWget ( String [] args ) throws Exception {

    System.out.println(httpRequest);
    System.out.println(proxyHost);
    System.out.println(ftpPort);

  urlConnection = setupProxy ( args );

        if (!nonverbose) {
            System.out.println("Connecting to " + httpRequest + "...");
            if(
0==httpRequest.compareTo("http://www.p2p.wrox.com/listindex.asp") ) //
hangs
             return false;
            if(
0==httpRequest.compareTo("http://www.soton.ac.uk/~chst/direct.htm") )
// hangs
             return false;
            if(
0==httpRequest.compareTo("https://www.ahamembership.com/assoc6/k.cgi?p=10-TX&acct_code=TX004-10TX-T")
) // security exception
             return false;
            if(
0==httpRequest.compareTo("https://www25.hway.net/onl261/cgi-local/sgx/shop.cgi?page=order.html&afnum=21")
) // security exception
             return false;
            if( 0==httpRequest.compareTo("https://grc.com/x/ne.dll?bh0bkyd2") )
// security exception
             return false;
        }
        try
            {
            DataOutputStream    printout;
            DataInputStream    input;

        urlConnection.setDoInput (true);
        urlConnection.setUseCaches (false);
        urlConnection.setRequestProperty("Accept","text/xml,text/*,text/html");
        urlConnection.setRequestProperty("Cache-Control","no-cache");

        if (null != strXML)  // add XML data as HTTP payload
        {  System.out.println("Adding XML...");
        // Send POST output.
        printout = new DataOutputStream (urlConnection.getOutputStream ());
        String content =
        "CoNUM=" + URLEncoder.encode ("2") +
        "&PASSWORD=" + URLEncoder.encode ("1");
            String msg;
msg = "<?xml version=" + "\"" + "1.0" + "\"" + "?>";
msg = msg + "</XML>";
    content = msg;
            System.out.println( " --- XML to Web Server ---\r\r" + content );
        printout.writeBytes (content);
        printout.flush ();
        printout.close ();
}
       }
    catch (MalformedURLException me)
        {
        System.err.println("MalformedURLException: " + me);
        }
    catch (IOException ioe)
        {
        System.err.println("IOException: " + ioe.getMessage());
        }
        if( !readHttp() )
         return false;
        closeAll();
        return true;
    }

    private void getOptions( String[] args ) throws Exception {
        for (int i=0; i<args.length; i++) {
            if (args[i].equals("-h")) {
                StringTokenizer st = new StringTokenizer(args[i+1], ":");
                int count=0;
                while (st.hasMoreTokens()) {
                    if (count == 0 ) {
                        proxyHost=st.nextToken();
                    }
                    if (count == 1) {
                        proxyPort=st.nextToken();
                    }
                    count++;
                }
                if (proxyPort == null) {
                    proxyPort = "80";
                }
                i++;
                notAssigned=false;
            }
            if (args[i].equals("-u")) {
                username=args[i+1];
                i++;
                notAssigned=false;
            }
            if (args[i].equals("-p")) {
                password=args[i+1];
                i++;
                notAssigned=false;
            }
            if (args[i].equals("-t")) {
                proxyType=args[i+1];
                i++;
                notAssigned=false;
            }
            if (args[i].equals("-post")) {
                formValues=args[i+1];
                i++;
                notAssigned=false;
            }
            if (args[i].equals("-method")) {
                formMethod=args[i+1];
                i++;
                notAssigned=false;
            }
            if( args[i].equals("-xml") ) // get XML file
            { strXML = new String("<XML></XML>");
            }
            if (proxyHost != null && ftpTrue==true) {
                if (!nonverbose) {
                    System.err.println("Proxy and Ftp cannot coexist use -h or -ftp");
                } else {
                    throw new Exception("Proxy and Ftp cannot coexist use -h or
-ftp");
                }
                return;
            }
            if (notAssigned) {
                httpRequest=args[i];
                if (httpRequest.substring(0, 5).equalsIgnoreCase("https")) {
                    https=true;
                }
            }
            notAssigned=true;
        }
    }

    /** Main invoked from the prompt.
    * @param args Arguments from the Stdin
    * @throws Exception Throws Exception
    */
    static String[] urls = {"http://www.youart.net/",
"http://www.microsoft.net/",
                            "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
                            "http://www.nbc.com/", "http://www.abc.com/",
                            "http://www.cbs.com/", "http://www.bbc.com/",
                            "http://www.ebay.com/", "http://www.yahoo.com/",
                            "http://www.ncr.com/", "http://www.ibm.com/",
                            "http://www.ford.com/", "http://www.cisco.com/",
                            "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
                            "http://www.cnn.com/"};
    public static void main ( String[] args ) throws Exception {

    for( int e=0; e<urls.length; e++)
    {    Leaky wget = new Leaky();
        wget.doWget( urls[e] );
        String result = wget.getOutput();
        System.out.println( "page has " + result.length() + " characters" );
        wget.zeroMem();
        wget=null;
System.gc();
System.gc();
System.gc();
    }
    // memory is leaked at this point. Next memory is magically returned
if we sleep awhile.
   for( int s=0; s<60; s++ ) {
       try{ Thread.sleep(60000);}catch(Exception e){}
        System.gc();
   }
}
Andrew Thompson - 03 Jun 2005 06:26 GMT
...
>     public String strXML = null;

Please refrain form posting tab characters to usenet, as they are
often expanded to ridiculous lengths by news reader software.  And
keep your line lengths short.  Otherwise lines wrap, and therefore break..
...
>                 System.err.println("Malformed URL, must be
> http://somehost[/file]");

Also, you are missing a closing '}'.  If you had stuck to a single
convention for formatting code, this might be easier to spot, but it
seems you are mixing and matching..

When those problems are fixed, I get..

C:\..\Leaky.java:60: cannot find symbol
symbol  : method encodeHttpString(java.lang.String)
location: class Leaky
                       httpRequest = httpRequest + "?" +
encodeHttpString(formValues);
                                                         ^
C:\..\Leaky.java:114: cannot find symbol
symbol  : class Base64
location: class Leaky
                       Base64 base64 = new Base64(username + ":" +
password);
                       ^
C:\..\Leaky.java:114: cannot find symbol
symbol  : class Base64
location: class Leaky
                       Base64 base64 = new Base64(username + ":" +
password);
                                           ^
C:\..\Leaky.java:203: cannot find symbol
symbol  : method readHttp()
location: class Leaky
               if( !readHttp() )
                    ^
C:\..\Leaky.java:205: cannot find symbol
symbol  : method closeAll()
location: class Leaky
               closeAll();
               ^
C:\..\Leaky.java:321: cannot find symbol
symbol  : method getOutput()
location: class Leaky
                       String result = wget.getOutput();
                                           ^
Note: C:\..\Leaky.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
6 errors

...It seems you might benefit from a document specifically prepared
to help people prepare a good example of a problem.  I suggest
(and recommend*) this one. <http://www.physci.org/codes/sscce.jsp>

* Not surprising, since I wrote and host it.

As far as the actual problem, I have no insights.  I was curious
to see your code break, but do not have a great deal of experience
with URLConnection (at least, not in terms of memory leaks).

Signature

Andrew Thompson
http://www.PhySci.org/codes/  Web & IT Help
http://www.PhySci.org/  Open-source software suite
http://www.1point1C.org/  Science & Technology
http://www.LensEscapes.com/  Images that escape the mundane

Knute Johnson - 03 Jun 2005 16:01 GMT
> URLConnection leaks memory and after a while will return the memory. No
> amount of calling System.gc(); will clean it up. OK for small apps but
[quoted text clipped - 348 lines]
>     }
> }

I have had problems in the past when I didn't close my
HttpURLConnection.  You might try that.

Signature

Knute Johnson
email s/nospam/knute/

Alan Krueger - 04 Jun 2005 05:18 GMT
[snip 350-some quoted lines]

> I have had problems in the past when I didn't close my
> HttpURLConnection.  You might try that.

Please try to trim quoted text before replying.  Quoting hundreds of
lines of text isn't really necessary to give context for a 1-2 line
response.
Knute Johnson - 05 Jun 2005 01:00 GMT
> [snip 350-some quoted lines]
>
[quoted text clipped - 4 lines]
> lines of text isn't really necessary to give context for a 1-2 line
> response.

bite me!

Signature

Knute Johnson
email s/nospam/knute/

timjowers@gmail.com - 04 Jun 2005 20:00 GMT
Thanks for everyone's feedback. I determined
1) closing input stream speeds up memory recovery (closeAll below)
2) setting references to null speeds up memory recovery (zeroMem below)
3) calling gc speeds up memory recovery. Of course, at a cost but if
mem is the over-arching problem as in my case then this cost may be
necessary. (System.gc, System.gc in thread class below)

I made a very simple example below (compiles as-is :-) and similar to
my real code which has lots of threads. I think these general memory
usage concepts will be applicable to other areas and get the
OutOfMemoryError under control. Also changed startup setting for Java.

Thanks for the feedback,
TimJowers

package WebGen;
/**
* Sample memory usage for URLConnection
*/
import java.net.*;
import java.io.*;

public class Leaky {

    private URL url=null;
    private URLConnection urlConnection=null;
    private InputStream is=null;
    private StringBuffer sbuf = null;
    private byte[] bytesRead = new byte[4096];

    protected void zeroMem()
    {
        url=null;
        urlConnection=null;
        is=null;
        sbuf = null;
        bytesRead = null;
    }

    public boolean doWget ( String httpRequest ) throws Exception {

    System.out.println(httpRequest);

    try {
        url = new URL(httpRequest);
    } catch (MalformedURLException e) {
            throw new Exception("Malformed URL, must be
http://somehost[/file]");
    }
    try {
        urlConnection = url.openConnection();
    } catch (IOException e) {
            throw new Exception("Error opening URL Connection to " +
httpRequest);
    }

    DataOutputStream     printout;
    DataInputStream        input;

    urlConnection.setDoInput (true);
    urlConnection.setUseCaches (false);
    // may need to set header  "Keep-Alive: close"
    urlConnection.setRequestProperty("Accept","text/xml,text/*,text/html");
    urlConnection.setRequestProperty("Cache-Control","no-cache");

    if( !readHttp() )
     return false;

    closeAll();

    return true;
}

    class TestLeaky extends Thread
    {
        String httpRequest;
        public void run() {
            Leaky wget = new Leaky();
            try{
                wget.doWget( httpRequest );
                String result = wget.getOutput();
                System.out.println( httpRequest + " page has " + result.length() +
" characters" );
                wget.zeroMem(); // actually speeds gc
                wget=null;
                System.gc(); // probably overkill but best way to minimize memory
usage
                System.gc();
            } catch( Exception e) {
                System.err.println( e );
            }
        }
    }

    /** Main invoked from the prompt.
    * @param args Arguments from the Stdin
    * @throws Exception Throws Exception
    */
    static String[] urls = {"http://www.youart.net/",
"http://www.microsoft.net/",
                            "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
                            "http://www.nbc.com/", "http://www.abc.com/",
                            "http://www.cbs.com/", "http://www.bbc.com/",
                            "http://www.ebay.com/", "http://www.yahoo.com/",
                            "http://www.ncr.com/", "http://www.ibm.com/",
                            "http://www.ford.com/", "http://www.cisco.com/",
                            "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.ncr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.ebay.com/", "http://www.yahoo.com/",
        "http://www.googlr.com/", "http://www.ibm.com/",
        "http://www.ford.com/", "http://www.cisco.com/",
        "http://www.honda.com/", "http://www.toyota.com/",
        "http://www.talkbackforum.com/", "http://www.unitedswe.com/",
        "http://www.nbc.com/", "http://www.abc.com/",
        "http://www.cbs.com/", "http://www.bbc.com/",
        "http://www.qbert.com/", "http://www.yahoo.com/",
        "http://www.starwars.com/", "http://www.nasa.gov/",
        "http://www.startrek.com/", "http://www.cisco.com/",
        "http://www.starman.com/", "http://www.mars.com/",
                            "http://www.cnn.com/"};
    public static void main ( String[] args ) throws Exception {

    Leaky lek = new Leaky();
    for( int e=0; e<urls.length; e++)
    {    TestLeaky thrd = lek.new TestLeaky();
        thrd.httpRequest = urls[e];
        thrd.start();
    }

    System.gc();
    System.gc();
    System.gc();
    // memory is leaked at this point. Next memory is magically returned
if we sleep awhile.
   for( int s=0; s<60; s++ ) {
       try{ Thread.sleep(5000);}catch(Exception e){}
        System.gc();
   }
}

    public Leaky() {    }

    private void closeAll() {
        if( urlConnection != null )
        try {
            urlConnection.getInputStream().close();
            if( urlConnection.getDoOutput() == true )
                urlConnection.getOutputStream().close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        urlConnection = null;
        url = null;
        is = null;
        //System.gc();
    }
    private boolean readHttp() throws Exception {
        try {
            sbuf = new StringBuffer();
            is = urlConnection.getInputStream();
            if (urlConnection.getHeaderField("Set-Cookie") != null) {
                    System.out.println(urlConnection.getHeaderField("Set-Cookie"));
                    sbuf.append(urlConnection.getHeaderField("Set-Cookie"));
            }
            int amount=0;
            System.out.println("Connected, retrieving file...");
            while ((amount = is.read(bytesRead)) > 0) {
                //System.out.println( "Just read bytes " + amount );
                    for (int i=0; i<amount; i++) {
                            sbuf.append((char)bytesRead[i]);
                    }
            }
        } catch (IOException e) {
            System.err.println( e );
          return false;
        }

        try {
            is.close();
        } catch (IOException e) {
                System.err.println("Error closing connection.");
            return false;
        }
        return true;
    }

    /** Returns the String returned by the Operation, like the content of
a Web page.
    * @return Returns a String object containing the received information
    */
    public String getOutput() {
        if( sbuf == null ) return "";
        String output = sbuf.toString();
        //sbuf.delete(0,sbuf.length());
        //sbuf = null;        
        return output;
    }
}
Thomas Weidenfeller - 06 Jun 2005 08:41 GMT
> Thanks for everyone's feedback. I determined
> 1) closing input stream speeds up memory recovery (closeAll below)
> 2) setting references to null speeds up memory recovery (zeroMem below)
> 3) calling gc speeds up memory recovery. Of course, at a cost but if
> mem is the over-arching problem as in my case then this cost may be
> necessary. (System.gc, System.gc in thread class below)

2) is seldom needed (only if the method will hold onto the reference for
a long time after the object is needed). 3) is usually not needed at
all. The JVM will run the GC when it becomes low on memory. So when you
see an out of memory error, the JVM really has no memory, and did
previously try "everything" to gain free memory. A manual attempt to run
the GC is no different from a JVM's automatic attempt to run the GC.

Running the GC manually can not clean up any references you accidentally
hold on to. The GC can't fix coding errors. Get a memory profiler to
figure out who holds the references. Manually calling the GC just
needlessly burns CPU cycles.

/Thomas

Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq

Chris Uppal - 06 Jun 2005 09:27 GMT
> 3) is usually not needed at
> all. The JVM will run the GC when it becomes low on memory. So when you
> see an out of memory error, the JVM really has no memory, and did
> previously try "everything" to gain free memory. A manual attempt to run
> the GC is no different from a JVM's automatic attempt to run the GC.

The point is that if some external resource ends up being managed (whether by
design or by accident) by finalisation (or reference queues, etc), then manual
GC may allow the finalisation process to 'see' the no-longer-needed resources
and clean them up /before/ the JVM realises that it needs to reclaim memory.
Not a good solution, and one that is never /guaranteed/ to work, but it can
help in some circumstances.

   -- chris
Kevin McMurtrie - 04 Jun 2005 18:36 GMT
Your code isn't even close to complete.  The interesting parts, like
what you do with the input stream, is missing.

Generally, temporary hangs and memory leaks are caused by not completing
the streams or abandoning HTTP 1.1 connections without specifying  
"Keep-Alive: close" in the header.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.