Do I have to close all streams from Process Class after using theProcess object?

S

sunkeunlee

Hi,

I have to use Process proc = Runtime.getRuntime().exec() method to
execute OS level command such as lpr. When I traced Java source code,
Process class's getErrorStream(), getInputStream(), and
getOutputStream() methods are instantiated inside ProcessImpl
constructor. My question is do I have to close all these streams
regardless of using in my program or not to prevent any resource leak?

Source Code:
stdin_stream =
new BufferedOutputStream(new FileOutputStream(stdin_fd));
stdout_stream =
new BufferedInputStream(new FileInputStream(stdout_fd));
stderr_stream =
new FileInputStream(stderr_fd);


My code example:

Process proc = Runtime.getRuntime().exec( cmdLine.toString() );
InputStream inStrm = proc.getInputStream();
//
....

If ( inStrm != null )
inStrm.close();

Should I call the close() method for stderr_stream and stdout_stream
also even though I don't use it?

Thanks,
Sun
 
R

Roedy Green

. My question is do I have to close all these streams
regardless of using in my program or not to prevent any resource leak?

my understanding is YES, even if you don't use them.
 
E

External Concepts Guild

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I have to use Process proc = Runtime.getRuntime().exec() method to
execute OS level command such as lpr. When I traced Java source code,
Process class's getErrorStream(), getInputStream(), and
getOutputStream() methods are instantiated inside ProcessImpl
constructor. My question is do I have to close all these streams
regardless of using in my program or not to prevent any resource leak?

Source Code:
stdin_stream =
new BufferedOutputStream(new FileOutputStream(stdin_fd));
stdout_stream =
new BufferedInputStream(new FileInputStream(stdout_fd));
stderr_stream =
new FileInputStream(stderr_fd);

My code example:

Process proc = Runtime.getRuntime().exec( cmdLine.toString() );
InputStream inStrm = proc.getInputStream();
//
...

If ( inStrm != null )
inStrm.close();

Should I call the close() method for stderr_stream and stdout_stream
also even though I don't use it?

Thanks,
Sun

Your question is interesting. Below is a simple testing program I
devised to experimentally answer the question.

This program will create a user specified number of processes. The
user can specify whether the program will maintain a hard or soft
reference to the process and whether it will close the streams
associated with the process.

When I asked the program to create 339 processes without closing the
associated streams, the program created 338 processes and crashed on
the 339th. However when I asked the program to create 339 processes
and close the associated streams, the program ran successfully. This
experiment suggests that there is a resource leakage associated with
not closing the process associated streams.

I hope this helps.

Emory Merryman
External Concepts Guild

final class TestLeaking
{
public static final void main ( final java . lang . String [ ]
args ) throws java . lang . Exception
{
final int count = java . lang . Integer . parseInt ( args [ 0 ] ) ;
int i = 0 ;
final boolean strongRef = java . lang . Boolean . parseBoolean ( args
[ 1 ] ) ;
final boolean weakRef = java . lang . Boolean . parseBoolean ( args
[ 2 ] ) ;
final boolean closeInputStream = java . lang . Boolean . parseBoolean
( args [ 3 ] ) ;
final boolean closeOutputStream = java . lang . Boolean .
parseBoolean ( args [ 4 ] ) ;
final boolean closeErrorStream = java . lang . Boolean . parseBoolean
( args [ 5 ] ) ;
final long start = new java . util . Date ( ) . getTime ( ) ;
final java . lang . Runtime runtime = java . lang . Runtime .
getRuntime ( ) ;
try
{
for ( i = 0 ; i < count ; i ++ )
{
process ( runtime , strongRef , weakRef , closeInputStream ,
closeOutputStream , closeErrorStream ) ;
}
}
finally
{
final long stop = new java . util . Date ( ) . getTime ( ) ;
final int k = processes . size ( ) ;
final long elapsed = stop - start ;
java . lang . System . out . println ( i + "\t" + count + "\t" +
strongRef + "\t" + weakRef + "\t" + closeInputStream + "\t" +
closeOutputStream + "\t" + closeErrorStream + "\t" + start + "\t" +
stop + "\t" + elapsed + "\t" + k ) ;
}
}

private static java . util . List < java . lang . Process >
processes = new java . util . ArrayList < java . lang . Process >
( ) ;

public static final void process ( final java . lang . Runtime
runtime , final boolean strongRef , final boolean weakRef , final
boolean closeInputStream , final boolean closeOutputStream , final
boolean closeErrorStream ) throws java . io . IOException
{
final java . lang . Process process = runtime . exec ( "ls" ) ;
if ( strongRef )
{
processes . add ( process ) ;
}
if ( weakRef )
{
waitForGC ( process ) ;
}
if ( closeInputStream )
{
final java . io . InputStream stream = process . getInputStream
( ) ;
stream . close ( ) ;
}
if ( closeOutputStream )
{
final java . io . OutputStream stream = process . getOutputStream
( ) ;
stream . close ( ) ;
}
if ( closeErrorStream )
{
final java . io . InputStream stream = process . getErrorStream
( ) ;
stream . close ( ) ;
}
}


public static final void waitForGC ( final java . lang . Process
process )
{
final java . lang . ref . Reference < java . lang . Process > ref =
new java . lang . ref . WeakReference < java . lang . Process >
( process ) ;
final java . lang . Runnable runnable = new java . lang . Runnable
( )
{
public final void run ( )
{
while ( ref . get ( ) != null )
{
}
}
} ;
final java . lang . Thread thread = new java . lang . Thread
( runnable ) ;
thread . start ( ) ;
}
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFHZzLrVQdj5Q2e9q0RAlbDAJ47FPFrQg0aOWOSCcU2cPEQ5z/4GwCff075
+rnog+D+PCh+bl1l18ZRnF0=
=hVhr
-----END PGP SIGNATURE-----
 
S

sunkeunlee

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I have to use Process proc = Runtime.getRuntime().exec() method to
execute OS level command such as lpr. When I traced Java source code,
Process class's getErrorStream(), getInputStream(), and
getOutputStream() methods are instantiated inside ProcessImpl
constructor. My question is do I have to close all these streams
regardless of using in my program or not to prevent any resource leak?
Source Code:
stdin_stream =
new BufferedOutputStream(new FileOutputStream(stdin_fd));
stdout_stream =
new BufferedInputStream(new FileInputStream(stdout_fd));
stderr_stream =
new FileInputStream(stderr_fd);
My code example:
Process proc = Runtime.getRuntime().exec( cmdLine.toString() );
InputStream inStrm = proc.getInputStream();
//
...
If ( inStrm != null )
inStrm.close();
Should I call the close() method for stderr_stream and stdout_stream
also even though I don't use it?
Thanks,
Sun

Your question is interesting. Below is a simple testing program I
devised to experimentally answer the question.

This program will create a user specified number of processes. The
user can specify whether the program will maintain a hard or soft
reference to the process and whether it will close the streams
associated with the process.

When I asked the program to create 339 processes without closing the
associated streams, the program created 338 processes and crashed on
the 339th. However when I asked the program to create 339 processes
and close the associated streams, the program ran successfully. This
experiment suggests that there is a resource leakage associated with
not closing the process associated streams.

I hope this helps.

Emory Merryman
External Concepts Guild

final class TestLeaking
{
public static final void main ( final java . lang . String [ ]
args ) throws java . lang . Exception
{
final int count = java . lang . Integer . parseInt ( args [ 0 ] ) ;
int i = 0 ;
final boolean strongRef = java . lang . Boolean . parseBoolean ( args
[ 1 ] ) ;
final boolean weakRef = java . lang . Boolean . parseBoolean ( args
[ 2 ] ) ;
final boolean closeInputStream = java . lang . Boolean . parseBoolean
( args [ 3 ] ) ;
final boolean closeOutputStream = java . lang . Boolean .
parseBoolean ( args [ 4 ] ) ;
final boolean closeErrorStream = java . lang . Boolean . parseBoolean
( args [ 5 ] ) ;
final long start = new java . util . Date ( ) . getTime ( ) ;
final java . lang . Runtime runtime = java . lang . Runtime .
getRuntime ( ) ;
try
{
for ( i = 0 ; i < count ; i ++ )
{
process ( runtime , strongRef , weakRef , closeInputStream ,
closeOutputStream , closeErrorStream ) ;
}
}
finally
{
final long stop = new java . util . Date ( ) . getTime ( ) ;
final int k = processes . size ( ) ;
final long elapsed = stop - start ;
java . lang . System . out . println ( i + "\t" + count + "\t" +
strongRef + "\t" + weakRef + "\t" + closeInputStream + "\t" +
closeOutputStream + "\t" + closeErrorStream + "\t" + start + "\t" +
stop + "\t" + elapsed + "\t" + k ) ;
}
}

private static java . util . List < java . lang . Process >
processes = new java . util . ArrayList < java . lang . Process >
( ) ;

public static final void process ( final java . lang . Runtime
runtime , final boolean strongRef , final boolean weakRef , final
boolean closeInputStream , final boolean closeOutputStream , final
boolean closeErrorStream ) throws java . io . IOException
{
final java . lang . Process process = runtime . exec ( "ls" ) ;
if ( strongRef )
{
processes . add ( process ) ;
}
if ( weakRef )
{
waitForGC ( process ) ;
}
if ( closeInputStream )
{
final java . io . InputStream stream = process . getInputStream
( ) ;
stream . close ( ) ;
}
if ( closeOutputStream )
{
final java . io . OutputStream stream = process . getOutputStream
( ) ;
stream . close ( ) ;
}
if ( closeErrorStream )
{
final java . io . InputStream stream = process . getErrorStream
( ) ;
stream . close ( ) ;
}
}

public static final void waitForGC ( final java . lang . Process
process )
{
final java . lang . ref . Reference < java . lang . Process > ref =
new java . lang . ref . WeakReference < java . lang . Process >
( process ) ;
final java . lang . Runnable runnable = new java . lang . Runnable
( )
{
public final void run ( )
{
while ( ref . get ( ) != null )
{
}
}
} ;
final java . lang . Thread thread = new java . lang . Thread
( runnable ) ;
thread . start ( ) ;
}}

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFHZzLrVQdj5Q2e9q0RAlbDAJ47FPFrQg0aOWOSCcU2cPEQ5z/4GwCff075
+rnog+D+PCh+bl1l18ZRnF0=
=hVhr
-----END PGP SIGNATURE------ Hide quoted text -

- Show quoted text -

Thanks all. I agree with your conclusion. The reason I posted this
question is I have an outofmemory error: unable to create a native
thread from a method that creates a Process and I found the code
doesn't close streams properly. If I don't call this metod the error
disappears. By the way, some reason our code creates more than 600
threads. Now I know how to resolve this issue.

Thanks,
Sun
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top