[由socketRead0分配的字符串TLAB

问题描述 投票:3回答:1

环境:

  1. Linux 4.x
  2. 异步分析器1.6(https://github.com/jvm-profiling-tools/async-profiler
  3. OpenJDK8

应用代码:

通过SocketInputStream的域套接字通信

动作:

使用异步分析器运行应用程序:-d 60 -e alloc -f /tmp/alloc.svg

问题:

来自SocketInputStream#socketRead0的意外的字符串分配

((cyan:TLAB分配)

enter image description here用于socketRead和socketRead0的JDK代码

private int socketRead(FileDescriptor fd,
                       byte b[], int off, int len,
                       int timeout)
    throws IOException {
    return socketRead0(fd, b, off, len, timeout);
}

private native int socketRead0(FileDescriptor fd,
                               byte b[], int off, int len,
                               int timeout)

本地套接字-Impl:

  • jdk / src / solaris / native / java / net / SocketInputStream.c
  • 假设:

字符串可能通过JNI在Java堆中分配,在下面的代码中,因为在字符串分配旁边的StackTrace中有一个SocketTimeoutException

Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
                                            jobject fdObj, jbyteArray data,
                                            jint off, jint len, jint timeout)
{
    [...]
    if (timeout) {
        nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
        if ((*env)->ExceptionCheck(env)) {
            if (bufP != BUF) {
                free(bufP);
            }
            return nread;
        }
    } else {
        nread = NET_Read(fd, bufP, len);
    }
    [...]
}

static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
    int result = 0;
    long prevtime = NET_GetCurrentTime(), newtime;
    while (timeout > 0) {
        result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);
        if (result <= 0) {
            if (result == 0) {
                JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out");
            } else if (result == -1) {
                if (errno == EBADF) {
                    JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
                } else if (errno == ENOMEM) {
                    JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
                } else {
                    JNU_ThrowByNameWithMessageAndLastError
                            (env, "java/net/SocketException", "select/poll failed");
                }
            }
            return -1;
        }
        result = NET_NonBlockingRead(fd, bufP, len);
        if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
            newtime = NET_GetCurrentTime();
            timeout -= newtime - prevtime;
            if (timeout > 0) {
                prevtime = newtime;
            }
        } else {
            break;
        }
    }
    return result;
}

因此,我有点想法,所以我搜索了C代码,但未找到任何jString分配。

有人知道可能在哪里分配字符串吗?

环境:Linux 4.x async-profiler 1.6(https://github.com/jvm-profiling-tools/async-profiler)OpenJDK8应用程序代码:通过SocketInputStream进行域套接字通信操作:使用...运行应用程序...

java jvm allocation async-profiler
1个回答
3
投票

您的假设是正确的。概要文件中的SocketTimeoutException告诉该方法分配了一个异常对象,并且该异常对象具有String消息,该消息也需要分配。

© www.soinside.com 2019 - 2024. All rights reserved.