• jni使用问题总结


    参考:

    https://blog.csdn.net/fred_lzy/article/details/53159138

    https://blog.csdn.net/avi3/article/details/83330334

    项目开发过程中,需要用到C/C++开源代码的功能,而框架是java环境,考虑到c++效率更高而且又有现成的,所以选择jni。碰到一些问题,最终都解决了,现总结如下:

    1、内存溢出错误Crash due to Stack Overflow

      程序运行过程中碰到第一篇博客中描述的问题4.1.3 Crash due to Stack Overflow,后来通过调整JVM参数,设置-Xss2m将内存溢出问题解决,若处理数据量上升到一定程度恐怕仍然会有问题。

    为降低内存使用,将c++中用到的全局变量依据应用需求适当缩小,同时将c++返回到java环境的对象也缩小,并重复利用,而不是重复new object(gc处理不及时内存占用比较高),同时还增加了手动内存回收(System.gc(),虽然有延迟但效果也不错)。

     2、jni部分env.FindClass(“java/util/ArrayList”)失败

      本来开源代码里基本都是纯C,变量都是全局的,后来对其进行拆解,封装关键代码,想用C++面向对象的思想封装成局部可用的对象,这样后续利用多线程提升处理效率也可行,结果碰到上述问题。

      因项目组其他成员直接对源码进行封装,使用的全局变量未出现该问题,所以以为C/C++转换到java的对象只能是全局变量。后来在调试问题1时发现,C++封装的源码中有个二维数组未赋初始值就使用,并且与0.0进行比较(如下),怀疑所有问题都是由于这个造成的,所以还是按照原思路整理封装的开源C代码,去掉冗余的部分(因是无线信号传播领域的算法,不太敢修改源代码,后来请教相关同事后去掉了大部分不需要的部分),问题得到解决。

    struct LR {
        double frq_mhz;
        double conf;
        double rel;
        float antenna[361][1001];
    };
    ...
      pattern =
    (double)LR.antenna[(int)azimuth][x];
      
    if (pattern != 0.0) {
    pattern = 20.0 * log10(pattern);
    loss -= pattern;
    }
    ...

    3、java数值出现NaN

     java环境下调用jni方法,返回NaN的double型数据,后来分别在java和C++环境下调试,输入同样的参数,在c++中特定参数为负值时也出现了NaN,发现开源算法中对浮点数的比较有问题,如2中提到的

    pattern != 0.0判断,作为log真数不能为负数,未经初始赋值的LR,float类型变量会在0左右浮动,这种判断语句就存在问题,应改为pattern > 0.0 或 pattern > 0.0000001




  • 相关阅读:
    到底有多少种智能指针(smart pointer)
    QSettings提供了非常方便的注册表读写
    阿里腾讯亿元级投资版图:阿里爱买超市,腾讯娱乐至上(恐怖)
    gcc安装教程(学习Linux编程只需安装cygwin)
    苹果抛弃的芯片公司Imagination被中资49亿溢价收购
    NET Core2
    HelloWorld RabbitMQ
    redis 集群
    kafka
    Impala简介PB级大数据实时查询分析引擎
  • 原文地址:https://www.cnblogs.com/HandyLi/p/10287680.html
Copyright © 2020-2023  润新知