Java 按socketRead0分配的字符串TLAB
环境:Java 按socketRead0分配的字符串TLAB,java,jvm,allocation,async-profiler,Java,Jvm,Allocation,Async Profiler,环境: Linux 4.x 异步探查器1.6() OpenJDK8 申请代码: 通过SocketInputStream进行域套接字通信 行动: 使用异步探查器运行应用程序:-d 60-e alloc-f/tmp/alloc.svg 问题: 来自SocketInputStream#socketRead0的意外字符串分配 private int socketRead(FileDescriptor fd, byte b[], int off, int le
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)
(青色:TLAB alloc)
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
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;
}
Java\u Java\u net\u SocketInputStream\u socketRead0(JNIEnv*env,jobject this,
jobject fdObj,jbyteArray数据,
吉特关,吉特蓝,吉特超时)
{
[...]
如果(超时){
nread=净读取超时(env、fd、bufP、len、超时);
如果((*env)->例外检查(env)){
如果(bufP!=BUF){
免费(bufP);
}
返回nread;
}
}否则{
nread=净读取(fd、bufP、len);
}
[...]
}
静态int NET_ReadWithTimeout(JNIEnv*env、int fd、char*bufP、int len、长超时){
int结果=0;
long prevtime=NET_GetCurrentTime(),newtime;
同时(超时>0){
结果=净时间超过当前时间(fd、超时、prevtime);
如果(结果0){
prevtime=newtime;
}
}否则{
打破
}
}
返回结果;
}
我搜索了C代码,没有找到任何jString分配,因此我有点想法
有人知道字符串分配可能发生在哪里吗?您的假设是正确的<概要文件中的code>SocketTimeoutException说明该方法分配了一个异常对象,并且该异常对象有一个
字符串
消息,该消息也需要分配
我刚刚提交了对async profiler的一个更改,它添加了--cstack
选项,用于在分配分析模式下记录C堆栈和Java堆栈。证明了java.lang.String
确实是从JNIThrowNew
函数分配的:
我从master构建了异步探查器,事实上,我确实看到了与您在示例中描述的--cstack相同的行为。谢谢你的贡献。