高分求教 matlabjni 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 还有就是matlab程序本身并没有因为调用多而耗时, 不管是开始还是后面每次执行耗时都差不多(在matlab程序里加入时间统计测试出的结果)。 所以问题也就是jni频繁调用相关的东西吧,但我并不确定, 也不知道如何解决。 测试打印的结果:第1w用时:4第2w用时:7第3w用时:22=====第1w用时:41第2w用时:51第3w用时:61 你有没有考虑System.currentTimeMillis(); 所花费的时间,你打出来的时间是JNI的执行时间还是java方法和JNI一起执行的时间?你是线程睡眠后再执行的第二个方法,你拆开执行看看所耗时间。 Object[] calResult = myCal.myCal(4, 2, 3);这个是多线程还是单线程?有无线程安全问题?有无同步问题? 就这么多代码,另外有两个jar, 给你也测试不了, 必需装matlab环境才能跑。 我现在初步确定了问题在返回值这块, Object[] calResult = myCal.myCal(4, 2, 3); 这个第一个参数是一个int 表示获几个返回值, 可以比matlab 函数返回值个数小, 同时也是calResult 数组的长度。 当我不获取返回值也就是Object[] calResult = myCal.myCal(0, 2, 3); 测试打印的时间稳定在2秒, 比较短且不会增长 在Object[] calResult = myCal.myCal(4, 2, 3);前后打印耗时时间看下效果 有没有做1W次之后dump一下内存看看呢?jstat看一下内存的使用情况 呢?我觉得JNI调用再多次也不会这样子,多数是什么地方有memory leak或者是线程未释放之类的问题导致的。 这个打印下结果是一次调用可能消耗0、16、32 毫秒。 且越往后出现16、32的次数越多。 也就是1w次会多出10多秒的样子, 再往里面就没法看了, 反编译出matlab的jar没有注释, 蛮复杂的,点到最里面就是native方法 怎么dump,具体要怎么操作呢? 我只是用jconsole看到jvm 内存正常 怎么dump,具体要怎么操作呢? 我只是用jconsole看到jvm 内存正常用jmap之类的看看你跑这么多次,内存没有增长 么? 先使用System.currentTimeMillis(); 打印看下是哪步耗时吧 你这一堆static,问题出在大作用域的MyCal里。建议你查看MyCal里的代码,是否存在未释放的资源啥的,或者在重复执行时影响执行效率的东东 把静态去掉 换成new的方式试试 JVM 与本机代码之间的通信通常很慢,因此,太多的 JNI 调用可能会降低性能 我在MT4中调用过matlab生成的DLL,调用速度的问题倒是没怎么留意,调用matlab只是为了验证matlab里提供的东西能不能解决我的问题,后来发现可以解决,就把matlab里的东西用JAVAl来实现,里面的东西大多有其他语言的替代实现,LZ可以找找 正确调用的代码是这样的:在使用完计算结果 Object[] calResult; 后加入 MWArray.disposeArray(calResult); 这么一句话。就是for (Object o : calResult) { MWNumericArray m = (MWNumericArray) o; m.dispose(); }通过debug发现 calResult 实际类型是MWNumericArray, 这个是matlab转为java后的一种数据类型(矩阵、向量、数值), 里面的一个NativeArray 很明显就是matlba 的数据(byte[])。 NativeArray 的 finalize方法被重写调用dispose()。 上面m.dispose(); 也就是调用内部NativeArray 的dispose()。看到这里大家获取有些疑惑, 因为finalize方法被垃圾回去的时候会自动被调用,也就是说calResult 出了作用域以后即会被调用dispose方法, 我们无需加入上面的代码。 我也真实因为这个观点才犯错的。这里有篇文章对于finalize可能引发内存溢出 http://ju.outofmemory.cn/entry/74671在例子(生产的例子不是测试例子)中并不会内存溢出(jvm设置的内存比较大), 但问题确实是Finalizer线程比主线程优先级低,当这么大的一直循环创建了大量Finalizer对象, 却没能被调用执行。 这个我通过jmap弄出dump文件后证实确实如此, 在测试内存快慢的的时候几乎全被Finalizer对象占有。手动调用dispose后正确解决了这个问题。想起之前看到Java编程思想还是jvm那本书里说 java程序员应该完全忘记finalize方法。在国外网上查到所有调用matlab的例子中都会像上面显示调用dispose, 然后带句注释//clean up the resources used by the generated MATLAB code. 获取//free native resources 并没说dispose最终做了什么, 反编译出的代码里面是native调用。 我猜测是java调用Matlab使用了Direct Memory然后我通过-XX:MaxDirectMemorySize=1M测试无变化,应该也不是Direct Memory被大量占用的问题。目前就知道这些东西, 问题已经解决, 但我还是不知道Java调用matlab机制是什么, dispose的native方法到底做了什么。 其实就是这个测试产生的垃圾内存,JVM根本来不及收集的意思? 不是jvm内存可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。 不是jvm内存可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。其实,我一直很好奇你原来的代码中 gc的情况到底 是如何的。照这个文章的说法,应该分析蛮透的了啊。finalize的时候还要通过JNI去调用,而那个文章说一旦finalize有内容的话,又会直接到FGC上面去。这样,FGC相关的参数就会对性能影响很大了。 不是jvm内存可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。其实,我一直很好奇你原来的代码中 gc的情况到底 是如何的。照这个文章的说法,应该分析蛮透的了啊。finalize的时候还要通过JNI去调用,而那个文章说一旦finalize有内容的话,又会直接到FGC上面去。这样,FGC相关的参数就会对性能影响很大了。频繁full gc肯定是不行的, 测试是也确实如此,应为不管新生代还是老生代都是一会就满了(我设的值小),全被Finalizer占了没办法只能full gc,并不是因为finalize。 matlab的工具包作者有意或者好心重写了finalize方法, 在里面做了开发人员应该手动调用的dispose。 但这个好心并不能完全奏效,原因就是那篇文章说的, 出现这种情况是因为太频繁创建重写了finalize的对象,Finalizer线程跟不上了。对于我生产中也确实产生了大量的Finalizer, 但这对于我服务器jvm配置还是小菜一碟, 我但是测试跑了几乎一个下午jvm老生代也没满呢。 问题就是dispose 里面的jni调用必需手动及时的做。 它里面是清理的matlab的一些东西。 那会不会是dispose产生了一个无法多线程工作现象呢? 新手问个sql 注入问题。 不能连接到这个某个连接文件里 怎样设置JTable的单元格只能输入数字? 关于 JAVA 和 c#错误处理 的对比,比较深奥的问题,请高手解答? 面试题目 PHP的crypt()生成的密文,我用java怎么验证? 求助:JAVA的解释器的问题 java如何实现将两个数组中不同的元素放到另一个数组中(不用集合) win2000下编译java程序看不到运行结果的问题,今天解决加到100分!!! 如何解决WEB中打印问题?(急!!!) java基础知识总结分享 离散数学
第2w用时:7
第3w用时:22
=====
第1w用时:41
第2w用时:51
第3w用时:61
你是线程睡眠后再执行的第二个方法,你拆开执行看看所耗时间。
我现在初步确定了问题在返回值这块, Object[] calResult = myCal.myCal(4, 2, 3); 这个第一个参数是一个int 表示获几个返回值, 可以比matlab 函数返回值个数小, 同时也是calResult 数组的长度。 当我不获取返回值也就是Object[] calResult = myCal.myCal(0, 2, 3); 测试打印的时间稳定在2秒, 比较短且不会增长
Object[] calResult = myCal.myCal(4, 2, 3);
前后打印耗时时间看下效果
这个打印下结果是一次调用可能消耗0、16、32 毫秒。 且越往后出现16、32的次数越多。
也就是1w次会多出10多秒的样子, 再往里面就没法看了, 反编译出matlab的jar没有注释, 蛮复杂的,点到最里面就是native方法
怎么dump,具体要怎么操作呢? 我只是用jconsole看到jvm 内存正常
怎么dump,具体要怎么操作呢? 我只是用jconsole看到jvm 内存正常用jmap之类的看看你跑这么多次,内存没有增长 么?
调用matlab只是为了验证matlab里提供的东西能不能解决我的问题,
后来发现可以解决,就把matlab里的东西用JAVAl来实现,
里面的东西大多有其他语言的替代实现,LZ可以找找
MWNumericArray m = (MWNumericArray) o;
m.dispose();
}通过debug发现 calResult 实际类型是MWNumericArray, 这个是matlab转为java后的一种数据类型(矩阵、向量、数值), 里面的一个NativeArray 很明显就是matlba 的数据(byte[])。 NativeArray 的 finalize方法被重写调用dispose()。 上面m.dispose(); 也就是调用内部NativeArray 的dispose()。看到这里大家获取有些疑惑, 因为finalize方法被垃圾回去的时候会自动被调用,也就是说calResult 出了作用域以后即会被调用dispose方法, 我们无需加入上面的代码。 我也真实因为这个观点才犯错的。
这里有篇文章对于finalize可能引发内存溢出 http://ju.outofmemory.cn/entry/74671在例子(生产的例子不是测试例子)中并不会内存溢出(jvm设置的内存比较大), 但问题确实是Finalizer线程比主线程优先级低,当这么大的一直循环创建了大量Finalizer对象, 却没能被调用执行。 这个我通过jmap弄出dump文件后证实确实如此, 在测试内存快慢的的时候几乎全被Finalizer对象占有。手动调用dispose后正确解决了这个问题。想起之前看到Java编程思想还是jvm那本书里说 java程序员应该完全忘记finalize方法。在国外网上查到所有调用matlab的例子中都会像上面显示调用dispose, 然后带句注释
//clean up the resources used by the generated MATLAB code. 获取
//free native resources
并没说dispose最终做了什么, 反编译出的代码里面是native调用。 我猜测是java调用Matlab使用了Direct Memory
然后我通过-XX:MaxDirectMemorySize=1M测试无变化,应该也不是Direct Memory被大量占用的问题。目前就知道这些东西, 问题已经解决, 但我还是不知道Java调用matlab机制是什么, dispose的native方法到底做了什么。
可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。
可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。
其实,我一直很好奇你原来的代码中 gc的情况到底 是如何的。照这个文章的说法,应该分析蛮透的了啊。finalize的时候还要通过JNI去调用,而那个文章说一旦finalize有内容的话,又会直接到FGC上面去。这样,FGC相关的参数就会对性能影响很大了。
可能我没说清楚, 慢的问题解决了,但原因还不知道。上面只是说 finalize方法的一些东西。 大量的Finalizer并不是慢的原因。
其实,我一直很好奇你原来的代码中 gc的情况到底 是如何的。照这个文章的说法,应该分析蛮透的了啊。finalize的时候还要通过JNI去调用,而那个文章说一旦finalize有内容的话,又会直接到FGC上面去。这样,FGC相关的参数就会对性能影响很大了。频繁full gc肯定是不行的, 测试是也确实如此,应为不管新生代还是老生代都是一会就满了(我设的值小),全被Finalizer占了没办法只能full gc,并不是因为finalize。 matlab的工具包作者有意或者好心重写了finalize方法, 在里面做了开发人员应该手动调用的
dispose。 但这个好心并不能完全奏效,原因就是那篇文章说的, 出现这种情况是因为太频繁创建重写了finalize的对象,Finalizer线程跟不上了。对于我生产中也确实产生了大量的Finalizer, 但这对于我服务器jvm配置还是小菜一碟, 我但是测试跑了几乎一个下午jvm老生代也没满呢。 问题就是dispose 里面的jni调用必需手动及时的做。 它里面是清理的matlab的一些东西。