Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6909089

Memory leak occurs by lack of free for read buffer in SocketInputStream#read()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • 7
    • 7
    • core-libs
    • b79
    • x86
    • windows_xp

      A JavaSE licensee's customer faces with serious crash because of exhaustion of native heap.
      This crash seems caused by lack of free operation for InputStream read buffer(native).

      INVESTIGATION:
      The following source code portion is extracted from jdk7b76.

      ==== ./jdk/src/windows/native/java/net/SocketInputStream.c ===>
      ........
          60 JNIEXPORT jint JNICALL
          61 Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
          62 jobject fdObj, jbyteArray data,
          63 jint off, jint len, jint timeout
          64 {
          65 char *bufP;
          66 char BUF[MAX_BUFFER_LEN];
          67 jint fd, newfd;
          68 jint nread;
          69
          70 if (IS_NULL(fdObj)) {
          71 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
          72 return -1;
          73 }
          74 fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
          75 if (fd == -1) {
          76 NET_ThrowSocketException(env, "Socket closed");
          77 return -1;
          78 }
          79
          80 /*
          81 * If the caller buffer is large than our stack buffer then we allocate
          82 * from the heap (up to a limit). If memory is exhausted we always use
          83 * the stack buffer.
          84 */
          85 if (len <= MAX_BUFFER_LEN) {
          86 bufP = BUF;
          87 } else {
          88 if (len > MAX_HEAP_BUFFER_LEN) {
          89 len = MAX_HEAP_BUFFER_LEN;
          90 }
          91 bufP = (char *)malloc((size_t)len); // <==== Allocating Buffer
          92 if (bufP == NULL) {
          93 /* allocation failed so use stack buffer */
          94 bufP = BUF;
          95 len = MAX_BUFFER_LEN;
          96 }
          97 }
          98
          99
         100 if (timeout) {
         101 if (timeout <= 5000 || !isRcvTimeoutSupported) {
         102 int ret = NET_Timeout (fd, timeout);
         103
         104 if (ret <= 0) {
         105 if (ret == 0) {
         106 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
         107 "Read timed out");
         108 } else if (ret == JVM_IO_ERR) {
         109 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
         110 } else if (ret == JVM_IO_INTR) {
         111 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
         112 "Operation interrupted");
         113 }
         114 if (bufP != BUF) {
         115 free(bufP);
         116 }
         117 return -1;
         118 }
         119
         120 /*check if the socket has been closed while we were in timeout*/
         121 newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
         122 if (newfd == -1) {
         123 NET_ThrowSocketException(env, "Socket Closed");
         124 return -1; // <==== free(bufP) seems needed !
         125 }
         126 }
         127 }

      .........
      <================================================================


      Allocated memory area at line#71 doesn't seem freed when the program exits at line#124.
      This program flow path seems cause memory(native heap) leak.
      Actually, when the program exits at other "return"s (ex. line#114-117),
      allocated bufPs are freed.


      CONFIGURATION:
        JDK: jdk7b76/jdk6ux/jdk5ux
             (the latest verions of the above 3 have the same source code portion.)
        OS : WindowsXP/Vista/2008

            chegar Chris Hegarty
            tbaba Tadayuki Baba (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: