首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >String TLAB按socketRead0分配

String TLAB按socketRead0分配
EN

Stack Overflow用户
提问于 2020-01-05 16:25:45
回答 1查看 169关注 0票数 3

环境:

4.x

  • OpenJDK8

  1. Linux

申请-守则:

通过SocketInputStream进行域-套接字通信

操作:

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

问题:

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

(青色: TLAB alloc)

JDK- socketRead和socketRead0代码

代码语言:javascript
运行
复制
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)

本机套接字-推动:

  • jdk/src/solaris/native/java/net/SocketInputStream.c

假设:

字符串可能在java堆中通过JNI在下面的代码中的某个位置分配,因为在字符串分配旁边的StackTrace中有一个StackTrace。

代码语言:javascript
运行
复制
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分配,因此我是一种想法。

有人知道字符串分配在哪里发生吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-06 01:47:41

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

我刚刚提交了对异步分析器的更改,它添加了--cstack选项,用于在分配分析模式下记录C堆栈和Java堆栈。它证明了java.lang.String确实是从JNI ThrowNew函数中分配的:

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59601848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档