java - 通过 socketRead0 分配字符串 TLAB
问题描述
环境:
- Linux 4.x
- 异步分析器 1.6 ( https://github.com/jvm-profiling-tools/async-profiler )
- OpenJDK8
应用代码:
通过 SocketInputStream 进行域套接字通信
行动:
使用异步分析器运行应用程序:-d 60 -e alloc -f /tmp/alloc.svg
问题:
来自 SocketInputStream#socketRead0 的意外字符串分配
(青色: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)
本机 Socket-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 分配,因此我有点想法。
有人知道字符串分配可能发生在哪里吗?
解决方案
推荐阅读
- html - 固定大小背景下的空白区域
- reactjs - 反应:找不到此错误的解决方案:未捕获的 TypeError:clients.map 不是函数
- r - 从 R 中的 GoogleSheets 清除列表列表
- javascript - 这种流畅的 D3 方法调用是如何实现的?
- json - 使用页面令牌(android studio)获取 youtube 频道的所有视频
- r - R 使用 group_by 并汇总 7 个变量,但只得到一个结果?
- python - 如何使用熊猫在excel输出文件中合并具有相同内容的多个列
- c++ - A* 寻路算法中的育儿?
- sql - 如何在不使用滞后的情况下在偏移量旁边显示一列值
- python - 使用 optuna LightGBMTunerCV 作为 optuna 进一步搜索的起点