Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1685276
  • 博文数量: 347
  • 博客积分: 9328
  • 博客等级: 中将
  • 技术积分: 2680
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-29 23:45
文章分类

全部博文(347)

文章存档

2016年(1)

2013年(4)

2012年(207)

2011年(85)

2010年(50)

分类: C/C++

2012-05-20 00:52:22

补充:
对JAVA传入数据的处理
 1. 如果传入的是bytearray的话,作如下处理得到buffer:
  

点击(此处)折叠或打开

  1. char *tmpdata = (char*)(*env)->GetByteArrayElements(env, bytearray, NULL);
  2. (*env)->ReleaseByteArrayElements(env, bytearray, tmpdata, 0);



 
在c++中new的对象,如果不返回java,必须用release掉,否则内存泄露。包括NewStringUTF,NewObject
。如果返回java不必release,java会自己回收。

jstring jstr = env->NewStringUTF((*p).sess_id);
...
env->DeleteLocalRef( jstr);

jobject jobj = env->NewObject(clazz,midInit);
return jobj;

内存泄露可以先从windows资源管理器中,看到随程序运行,内存不断增长的趋势,具体可以用hp jmeter检测在运行程序时,加jvm参数 -Xrunhprof:heap=all,cutoff=0 ,生成java.hprof.txt,用jmeter打开,Metric -> Residual Objects (Count),可以看到未回收的对象,选中要查看的对象,点Mark记录下要查看的对象,Window -> New Window 打开新窗口,用Metric -> Reference Graph Tree,然后点Find Immediately可以看到对象被哪里引用。


另一方法

程序有内存泄漏的第一个迹象通常是它抛出一个 OutOfMemoryError,或者因为频繁的垃圾收集而表现出糟糕的性能。幸运的是,垃圾收集可以提供能够用来诊断内存泄漏的大量信息。如果以 -verbose:gc 或者 -Xloggc 选项调用 JVM,那么每次 GC 运行时在控制台上或者日志文件中会打印出一个诊断信息,包括它所花费的时间、当前堆使用情况以及恢复了多少内存。记录 GC 使用情况并不具有干扰性,因此如果需要分析内存问题或者调优垃圾收集器,在生产环境中默认启用 GC 日志是值得的。

有工具可以利用 GC 日志输出并以图形方式将它显示出来,JTune 就是这样的一种工具(请参阅 参考资料)。观察 GC 之后堆大小的图,可以看到程序内存使用的趋势。对于大多数程序来说,可以将内存使用分为两部分:baseline 使用和 current load 使用。对于服务器应用程序,baseline 使用就是应用程序在没有任何负荷、但是已经准备好接受请求时的内存使用,current load 使用是在处理请求过程中使用的、但是在请求处理完成后会释放的内存。只要负荷大体上是恒定的,应用程序通常会很快达到一个稳定的内存使用水平。如果在应用程序已经完成了其初始化并且负荷没有增加的情况下,内存使用持续增加,那么程序就可能在处理前面的请求时保留了生成的对象。


图 1 显示 GC 之后应用程序堆大小随着时间的变化图。上升趋势是存在内存泄漏的警示信号。(在真实的应用程序中,坡度不会这么大,但是在收集了足够长时间的 GC 数据后,上升趋势通常会表现得很明显。)



 

确信有了内存泄漏后,下一步就是找出哪种对象造成了这个问题。所有内存分析器都可以生成按照对象类进行分解的堆快照。有一些很好的商业堆分析工具,但是找出内存泄漏不一定要花钱买这些工具 —— 内置的 hprof 工具也可完成这项工作。要使用 hprof 并让它跟踪内存使用,需要以 -Xrunhprof:heap=sites 选项调用 JVM。

清单 3 显示分解了应用程序内存使用的 hprof 输出的相关部分。(hprof 工具在应用程序退出时,或者用 kill -3 或在 Windows 中按 Ctrl+Break 时生成使用分解。)注意两次快照相比,Map.Entry、Task 和 int[] 对象有了显著增加。

请参阅 清单 3

清单 4 展示了 hprof 输出的另一部分,给出了 Map.Entry 对象的分配点的调用堆栈信息。这个输出告诉我们哪些调用链生成了 Map.Entry 对象,并带有一些程序分析,找出内存泄漏来源一般来说是相当容易的。



TRACE 300446: java.util.HashMap$Entry.(:Unknown line) java.util.HashMap.addEntry(:Unknown line) java.util.HashMap.put(:Unknown line) java.util.Collections$SynchronizedMap.put(:Unknown line) com.quiotix.dummy.MapLeaker.newTask(MapLeaker.java:48) com.quiotix.dummy.MapLeaker.main(MapLeaker.java:64)


另外
jstring jstr = (jstring)env->CallObjectMethod(authenRequest, mid_authenReq_getSdId_S);
env->GetStringUTFRegion(jstr,0,env->GetStringLength(jstr),authenReq.sd_id);
当jstr是null时,env->GetStringLength(jstr)会出错,导致jvm崩溃
阅读(2071) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~