环境:
应用代码:
通过SocketInputStream的域套接字通信
动作:
使用异步分析器运行应用程序:-d 60 -e alloc -f /tmp/alloc.svg
问题:
来自SocketInputStream#socketRead0的意外的字符串分配
((cyan:TLAB分配)
用于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:
假设:
字符串可能通过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进行域套接字通信操作:使用...运行应用程序...
您的假设是正确的。概要文件中的SocketTimeoutException
告诉该方法分配了一个异常对象,并且该异常对象具有String
消息,该消息也需要分配。