ClarkGuan / jni

Go library for JNI
MIT License
51 stars 8 forks source link

代码中存在多处内存泄露,排查了一个月终于定位到问题 #5

Open aadog opened 8 months ago

aadog commented 8 months ago

代码中存在多处内存泄露,排查了一个月终于定位到问题 1.关于数组操作,cgo内存模型有误,修复如下

func (env Env) GetStringUTF(ptr Jstring) string {
    jstr := C.jstring(ptr)
    size := C.GetStringUTFLength((*C.JNIEnv)(unsafe.Pointer(env)), jstr)
    if size == 0 {
        return ""
    }
    ret := make([]byte, int(size)+1)
    C.GetStringUTFRegion((*C.JNIEnv)(unsafe.Pointer(env)), jstr, C.jsize(0), C.GetStringLength((*C.JNIEnv)(unsafe.Pointer(env)), jstr), cmem(ret))
    return string(ret)
}

类似这种错误有多处,这是导致崩溃和jvm异常的根本原因

ClarkGuan commented 3 weeks ago

代码中存在多处内存泄露,排查了一个月终于定位到问题 1.关于数组操作,cgo内存模型有误,修复如下

func (env Env) GetStringUTF(ptr Jstring) string {
  jstr := C.jstring(ptr)
  size := C.GetStringUTFLength((*C.JNIEnv)(unsafe.Pointer(env)), jstr)
  if size == 0 {
      return ""
  }
  ret := make([]byte, int(size)+1)
  C.GetStringUTFRegion((*C.JNIEnv)(unsafe.Pointer(env)), jstr, C.jsize(0), C.GetStringLength((*C.JNIEnv)(unsafe.Pointer(env)), jstr), cmem(ret))
  return string(ret)
}

类似这种错误有多处,这是导致崩溃和jvm异常的根本原因

@aadog 您好!

是否有相关复现的代码供参考? 我是根据 https://forums.oracle.com/ords/apexds/post/difference-between-getstringutfregion-and-getstringutfchars-0520 中的回复进行的编码。

aadog commented 2 weeks ago

不,这是cgo模型问题

ClarkGuan commented 1 week ago

不,这是cgo模型问题

@aadog 您可否提供一个简单复现问题的代码?

另外,我确定 Go 的 string 内存模型完全不需要留 1 byte 的所谓 C 字符串的 \0 结束符。 make([]byte, int(size)+1) 我不认为您这样写有意义,除非给出您其他的应用代码。