环境:
4.x
申请-守则:
通过SocketInputStream进行域-套接字通信
操作:
使用异步分析器运行应用程序:-d 60 -e alloc -f /tmp/alloc.svg
问题:
来自SocketInputStream#socketRead0的意外字符串分配
(青色: TLAB alloc)
JDK- socketRead和socketRead0代码
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)
本机套接字-推动:
假设:
字符串可能在java堆中通过JNI在下面的代码中的某个位置分配,因为在字符串分配旁边的StackTrace中有一个StackTrace。
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分配,因此我是一种想法。
有人知道字符串分配在哪里发生吗?
发布于 2020-01-05 17:47:41
你的假设是对的。配置文件中的SocketTimeoutException
告诉该方法分配一个异常对象,并且该异常对象具有一个也需要分配的String
消息。
我刚刚提交了对异步分析器的更改,它添加了--cstack
选项,用于在分配分析模式下记录C堆栈和Java堆栈。它证明了java.lang.String
确实是从JNI ThrowNew
函数中分配的:
https://stackoverflow.com/questions/59601848
复制