Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Java Machine > Out of memory w...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 1 Topic 748 of 803
Post > Topic >>

Out of memory with IBM's JDK Process implementation (possible DoS)

by krasimir.vanev@[EMAIL PROTECTED] Jan 19, 2007 at 01:18 AM

Hi,
The problem I'm describing is concerned with forking child process from
the JVM and out-of-memory due to communication with it.
The problem is concerned with IBM's JVM Process class implementation.
>From the
tests performed it seems the Process class consumes the data written on
the child's stdout even we don't do it explicitly, i.e.
Process.getInputStream().read(). In this case the data is buffered in
vector with byte array reference elements. It also seems that there's
no
limit for the number of elements in the vector, because the child
writes
till JVM out of memory crash.

With SUN's JVM the writer (forked process) blocks until the reader
(Java Process) reads the data from the pipe, which is the
normal IPC based on pipes.

The test consists of two programs:
- symb.c, which infinitely writes data to its STDOUT and registers the
number of writes done in symb.out file
- ProcessTest.java, which forks "symb" executable and only checks (and
prints on stdout) the number of bytes available on its InputStream
(symb's stdout).

With SUN's JVM the Java program shows that the number of available
bytes
is constant and in symb.out we have only one entry, i.e. only one write
is performed. With IBM's JVM the number of available bytes increases
till the JVM crash (the writer doesn't block). In the dump file we see
vector with references to bytes arrays: ProcessPipedInputStream
-> Vector -> array of byte with unlimited count.

Obviously the reader (java thread using Process) is slower than the
writer (forked C process) and a lot of data is buffered into the
endless Vector, which is the source of the random crashes with
out-of-memory.

I think that this is a bug in IBM's implementation. For now I don't
know is there any workaround for this. It'll be best if
there is some property (IBM specific) that specifiess the Array length
or s'thing similar.

Any comments and ideas are appreciated.

Regards,
Krasimir Vanev

Here are the test programs:
------------------------------symb.c----------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <dirent.h>
#include <signal.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/resource.h>


#define FILE_MODE   (mode_t)(S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR)

main()
{
    /*the data*/
    char buffer[65535];
    /*for logging*/
    char message[1024];

    /*redirect stderr to "symb.out" for logging*/
    int fd = open("symb.out", O_WRONLY|O_APPEND|O_CREAT, FILE_MODE);
    if (fd >= 0 && fd != STDERR_FILENO) {
        dup2(fd, STDERR_FILENO);
        close(fd);
    }


    for(;;) {
        if(fwrite(buffer, 65535, 1, stdout) != 1) {
            // error
            snprintf(message, 1023, "couldn't write to STDOUT\n");
            fwrite(message, strlen(message), 1, stderr);
        }
        snprintf(message, 1023, "written to STDOUT: 65535\n");
        fwrite(message, strlen(message), 1, stderr);

        fflush(stdout);
        fflush(stderr);
    }
}
------------------------------------------------------------------------------------------------------------------------------

-------------------------ProcessTest.java----------------------------------------------------------------------------
import java.io.BufferedInputStream;


public class ProcessTest {
        public Process getProcess() {
                Process process = null;
                try {
            // Hardcoded executable - "symb" from the current directory
                        process = Runtime.getRuntime().exec(new
String[] {"./symb"});
                        // We won't use err and out streams
                        process.getErrorStream().close();
                        process.getOutputStream().close();
                        return process;
                } catch (Exception e) {
                        System.err.println("getProcess() exception:" +
e.toString());
                        if (process != null) {
                                process.destroy();
                        }
                }

                return process;
        }

        public static void main(String[] args) {
                try {
                        ProcessTest test = new ProcessTest();
                        Process symb = test.getProcess();

                        BufferedInputStream symbIS = new
BufferedInputStream(symb.getInputStream());
                        int available = 0;

            //give the child enough time to fill in the buffer
            Thread.currentThread().sleep(1000);

                        while((available = symbIS.available()) > 0) {
                                System.out.println("Available to read:
" + available);
                        }
                        System.err.println("Exitting...available = " +
available);
                } catch (Exception e) {
            System.err.println("main() exception: " + e.toString());
        }
        }
}
------------------------------------------------------------------------------------------------------------------------




 1 Posts in Topic:
Out of memory with IBM's JDK Process implementation (possible Do
krasimir.vanev@[EMAIL PRO  2007-01-19 01:18:05 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Mon May 12 4:00:40 CDT 2008.