Runtime.getRuntime() Process Memory Leak Help

M

mike pitoniak

folks,

I have read all the posts and incorporated them into my code but
still the following code will ultimately leak the JVM down and throw a
java.lang.outofmemory error. I ahve tried everything to get the jvm to
release the process memory, but it just holds onto it. Can anyone help
me?

The code below should compile, and the main method will demontrate
the leak.

Many thanks for any help.

Best Regards,

mike

============================================================================

import harness.common.CommonConstants;
import harness.utils.classServices.ClassServices;
import harness.utils.exceptionServices.ExceptionServices;
import harness.utils.threadServices.BooleanLock;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io_OutputStream;
import java.io.PrintWriter;
import java.io.*;


public class SysExecCmdThread extends java.lang.Thread implements
CommonConstants {
private BooleanLock m_BooleanLock = null;
private String m_CmdStr = null;
private String m_Response = null;
private Runtime m_Runtime = null;
private StringBuffer m_ResponseBuffer = null;

public SysExecCmdThread(){
try{
m_Runtime = Runtime.getRuntime();
}catch(Exception e){
System.out.println(ClassServices.getCurrentMethodName() +
ExceptionServices.getStackTrace(e));
}
}

public SysExecCmdThread(BooleanLock bl, String cmd) {
m_BooleanLock = bl;
m_CmdStr = cmd;
}

public void run() {
m_Response = executeSystemCommand(m_CmdStr, null);
m_BooleanLock.setValue(true);
}

/* NOTE: on windows cmd paths that contain spaces must be quoted:
* ex) "\"c:/program files/windows/notepad.exe\""
**/
public String executeSystemCommand(String cmd, String
redirectFile){
Process process = null;
InputStream is = null;
InputStream es = null;
OutputStream os = null;
FileOutputStream fos = null;


try{
m_ResponseBuffer = new StringBuffer();

if(redirectFile != null){
fos = new FileOutputStream(redirectFile, false);
}
appendResponseBuffer("******************* Begin SysExecCmd
*******************\n");

process = m_Runtime.exec(cmd);

System.out.println(m_Runtime.freeMemory());
is = process.getInputStream();
es = process.getErrorStream();
os = process.getOutputStream();

StreamReader errorReader = new StreamReader(es, this,
"ERROR", fos);
StreamReader outputReader = new StreamReader(is, this,
"OUTPUT", fos);
errorReader.start();
outputReader.start();

while(outputReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}
while(errorReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}

int exitValue = process.waitFor();
appendResponseBuffer("ExitValue: " + exitValue + "\n");
appendResponseBuffer("******************** End SysExecCmd
********************\n");
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}finally{
try{
if(is != null){
is.close();
}
if(es != null){
es.close();
}
if(os != null){
os.close();
}
if(process != null){
process.destroy();
process = null;
}
m_Runtime.gc();
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}
}

return m_ResponseBuffer.toString();
}

public synchronized void appendResponseBuffer(String str) {
m_ResponseBuffer.append(str);
}

public String getResponse() {
return m_Response;
}

class StreamReader extends Thread {
InputStream is;
String type;
OutputStream os;
SysExecCmdThread m_SysExecCmdThread = null;
BufferedInputStream br = null;

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type) {
this(is, sysExecCmdThread, type, null);
}

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type, OutputStream redirect) {
this.is = is;
m_SysExecCmdThread = sysExecCmdThread;
this.type = type;
this.os = redirect;
}

public void run() {
StringBuffer sb = null;
BufferedReader m_BufferedReader = null;
String lineData = null;
try {


sb = new StringBuffer();

m_BufferedReader = new BufferedReader(new
InputStreamReader(is));
lineData = m_BufferedReader.readLine();
while(lineData != null){
sb.append(lineData + "\n");
lineData = m_BufferedReader.readLine();
//System.out.println(bufferData);
}
m_SysExecCmdThread.appendResponseBuffer(sb.toString()
+ "\n");
m_SysExecCmdThread.appendResponseBuffer("StreamReader
Completed: " + type + "\n");


} catch (IOException ioe) {
ioe.printStackTrace();
}finally{
try{
m_BufferedReader.close();
}catch(Exception e){}

}
}
}

public static void main(String args[]) {
int i=0;
SysExecCmdThread sysExecCmdThread = null;
while(true){
sysExecCmdThread = new SysExecCmdThread();
sysExecCmdThread.executeSystemCommand("CMD /C dir
c:\\windows", null);
System.out.println(i++);
//sysExecCmdThread.destroy();
sysExecCmdThread = null;
System.gc();
}
}

}
 
A

andrewh1

mike said:
folks,

I have read all the posts and incorporated them into my code but
still the following code will ultimately leak the JVM down and throw a
java.lang.outofmemory error. I ahve tried everything to get the jvm to
release the process memory, but it just holds onto it. Can anyone help
me?

First. I can't see why you would need to constantly create new threads.
I can't follow what you are trying to do but creating hundreds of
thousands of threads does seem a little unnecessary.

Do you need threads at all?

Second. The reason for the OutOfMemory error is that in your main
method you are creating a new SysExecCmdThread thread for every cycle,
but they never die. You cast them adrift but they are still alive and
hence cannot be GC'ed. If you really do need to use new threads you
should rewrite the code to call start() on each SysExecCmdThread object
as indicated in the docs for the Thread class. That works fine.

Andrew
The code below should compile, and the main method will demontrate
the leak.

Many thanks for any help.

Best Regards,

mike

============================================================================

import harness.common.CommonConstants;
import harness.utils.classServices.ClassServices;
import harness.utils.exceptionServices.ExceptionServices;
import harness.utils.threadServices.BooleanLock;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io_OutputStream;
import java.io.PrintWriter;
import java.io.*;


public class SysExecCmdThread extends java.lang.Thread implements
CommonConstants {
private BooleanLock m_BooleanLock = null;
private String m_CmdStr = null;
private String m_Response = null;
private Runtime m_Runtime = null;
private StringBuffer m_ResponseBuffer = null;

public SysExecCmdThread(){
try{
m_Runtime = Runtime.getRuntime();
}catch(Exception e){
System.out.println(ClassServices.getCurrentMethodName() +
ExceptionServices.getStackTrace(e));
}
}

public SysExecCmdThread(BooleanLock bl, String cmd) {
m_BooleanLock = bl;
m_CmdStr = cmd;
}

public void run() {
m_Response = executeSystemCommand(m_CmdStr, null);
m_BooleanLock.setValue(true);
}

/* NOTE: on windows cmd paths that contain spaces must be quoted:
* ex) "\"c:/program files/windows/notepad.exe\""
**/
public String executeSystemCommand(String cmd, String
redirectFile){
Process process = null;
InputStream is = null;
InputStream es = null;
OutputStream os = null;
FileOutputStream fos = null;


try{
m_ResponseBuffer = new StringBuffer();

if(redirectFile != null){
fos = new FileOutputStream(redirectFile, false);
}
appendResponseBuffer("******************* Begin SysExecCmd
*******************\n");

process = m_Runtime.exec(cmd);

System.out.println(m_Runtime.freeMemory());
is = process.getInputStream();
es = process.getErrorStream();
os = process.getOutputStream();

StreamReader errorReader = new StreamReader(es, this,
"ERROR", fos);
StreamReader outputReader = new StreamReader(is, this,
"OUTPUT", fos);
errorReader.start();
outputReader.start();

while(outputReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}
while(errorReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}

int exitValue = process.waitFor();
appendResponseBuffer("ExitValue: " + exitValue + "\n");
appendResponseBuffer("******************** End SysExecCmd
********************\n");
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}finally{
try{
if(is != null){
is.close();
}
if(es != null){
es.close();
}
if(os != null){
os.close();
}
if(process != null){
process.destroy();
process = null;
}
m_Runtime.gc();
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}
}

return m_ResponseBuffer.toString();
}

public synchronized void appendResponseBuffer(String str) {
m_ResponseBuffer.append(str);
}

public String getResponse() {
return m_Response;
}

class StreamReader extends Thread {
InputStream is;
String type;
OutputStream os;
SysExecCmdThread m_SysExecCmdThread = null;
BufferedInputStream br = null;

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type) {
this(is, sysExecCmdThread, type, null);
}

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type, OutputStream redirect) {
this.is = is;
m_SysExecCmdThread = sysExecCmdThread;
this.type = type;
this.os = redirect;
}

public void run() {
StringBuffer sb = null;
BufferedReader m_BufferedReader = null;
String lineData = null;
try {


sb = new StringBuffer();

m_BufferedReader = new BufferedReader(new
InputStreamReader(is));
lineData = m_BufferedReader.readLine();
while(lineData != null){
sb.append(lineData + "\n");
lineData = m_BufferedReader.readLine();
//System.out.println(bufferData);
}
m_SysExecCmdThread.appendResponseBuffer(sb.toString()
+ "\n");
m_SysExecCmdThread.appendResponseBuffer("StreamReader
Completed: " + type + "\n");


} catch (IOException ioe) {
ioe.printStackTrace();
}finally{
try{
m_BufferedReader.close();
}catch(Exception e){}

}
}
}

public static void main(String args[]) {
int i=0;
SysExecCmdThread sysExecCmdThread = null;
while(true){
sysExecCmdThread = new SysExecCmdThread();
sysExecCmdThread.executeSystemCommand("CMD /C dir
c:\\windows", null);
System.out.println(i++);
//sysExecCmdThread.destroy();
sysExecCmdThread = null;
System.gc();
}
}

}
 
M

mike pitoniak

Andrew,

so many thanks!

mp


andrewh1 said:
mike said:
folks,

I have read all the posts and incorporated them into my code but
still the following code will ultimately leak the JVM down and throw a
java.lang.outofmemory error. I ahve tried everything to get the jvm to
release the process memory, but it just holds onto it. Can anyone help
me?

First. I can't see why you would need to constantly create new threads.
I can't follow what you are trying to do but creating hundreds of
thousands of threads does seem a little unnecessary.

Do you need threads at all?

Second. The reason for the OutOfMemory error is that in your main
method you are creating a new SysExecCmdThread thread for every cycle,
but they never die. You cast them adrift but they are still alive and
hence cannot be GC'ed. If you really do need to use new threads you
should rewrite the code to call start() on each SysExecCmdThread object
as indicated in the docs for the Thread class. That works fine.

Andrew
The code below should compile, and the main method will demontrate
the leak.

Many thanks for any help.

Best Regards,

mike

============================================================================

import harness.common.CommonConstants;
import harness.utils.classServices.ClassServices;
import harness.utils.exceptionServices.ExceptionServices;
import harness.utils.threadServices.BooleanLock;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io_OutputStream;
import java.io.PrintWriter;
import java.io.*;


public class SysExecCmdThread extends java.lang.Thread implements
CommonConstants {
private BooleanLock m_BooleanLock = null;
private String m_CmdStr = null;
private String m_Response = null;
private Runtime m_Runtime = null;
private StringBuffer m_ResponseBuffer = null;

public SysExecCmdThread(){
try{
m_Runtime = Runtime.getRuntime();
}catch(Exception e){
System.out.println(ClassServices.getCurrentMethodName() +
ExceptionServices.getStackTrace(e));
}
}

public SysExecCmdThread(BooleanLock bl, String cmd) {
m_BooleanLock = bl;
m_CmdStr = cmd;
}

public void run() {
m_Response = executeSystemCommand(m_CmdStr, null);
m_BooleanLock.setValue(true);
}

/* NOTE: on windows cmd paths that contain spaces must be quoted:
* ex) "\"c:/program files/windows/notepad.exe\""
**/
public String executeSystemCommand(String cmd, String
redirectFile){
Process process = null;
InputStream is = null;
InputStream es = null;
OutputStream os = null;
FileOutputStream fos = null;


try{
m_ResponseBuffer = new StringBuffer();

if(redirectFile != null){
fos = new FileOutputStream(redirectFile, false);
}
appendResponseBuffer("******************* Begin SysExecCmd
*******************\n");

process = m_Runtime.exec(cmd);

System.out.println(m_Runtime.freeMemory());
is = process.getInputStream();
es = process.getErrorStream();
os = process.getOutputStream();

StreamReader errorReader = new StreamReader(es, this,
"ERROR", fos);
StreamReader outputReader = new StreamReader(is, this,
"OUTPUT", fos);
errorReader.start();
outputReader.start();

while(outputReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}
while(errorReader.isAlive()){try{Thread.sleep(50);}catch(Exception
e){}}

int exitValue = process.waitFor();
appendResponseBuffer("ExitValue: " + exitValue + "\n");
appendResponseBuffer("******************** End SysExecCmd
********************\n");
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}finally{
try{
if(is != null){
is.close();
}
if(es != null){
es.close();
}
if(os != null){
os.close();
}
if(process != null){
process.destroy();
process = null;
}
m_Runtime.gc();
}catch(Exception e){
appendResponseBuffer(ClassServices.getCurrentMethodName()
+ ExceptionServices.getStackTrace(e));
}
}

return m_ResponseBuffer.toString();
}

public synchronized void appendResponseBuffer(String str) {
m_ResponseBuffer.append(str);
}

public String getResponse() {
return m_Response;
}

class StreamReader extends Thread {
InputStream is;
String type;
OutputStream os;
SysExecCmdThread m_SysExecCmdThread = null;
BufferedInputStream br = null;

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type) {
this(is, sysExecCmdThread, type, null);
}

StreamReader(InputStream is, SysExecCmdThread
sysExecCmdThread, String type, OutputStream redirect) {
this.is = is;
m_SysExecCmdThread = sysExecCmdThread;
this.type = type;
this.os = redirect;
}

public void run() {
StringBuffer sb = null;
BufferedReader m_BufferedReader = null;
String lineData = null;
try {


sb = new StringBuffer();

m_BufferedReader = new BufferedReader(new
InputStreamReader(is));
lineData = m_BufferedReader.readLine();
while(lineData != null){
sb.append(lineData + "\n");
lineData = m_BufferedReader.readLine();
//System.out.println(bufferData);
}
m_SysExecCmdThread.appendResponseBuffer(sb.toString()
+ "\n");
m_SysExecCmdThread.appendResponseBuffer("StreamReader
Completed: " + type + "\n");


} catch (IOException ioe) {
ioe.printStackTrace();
}finally{
try{
m_BufferedReader.close();
}catch(Exception e){}

}
}
}

public static void main(String args[]) {
int i=0;
SysExecCmdThread sysExecCmdThread = null;
while(true){
sysExecCmdThread = new SysExecCmdThread();
sysExecCmdThread.executeSystemCommand("CMD /C dir
c:\\windows", null);
System.out.println(i++);
//sysExecCmdThread.destroy();
sysExecCmdThread = null;
System.gc();
}
}

}
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top