当前位置: 首页 > news >正文

工商网站如何做企业增资网站建设中英语

工商网站如何做企业增资,网站建设中英语,智慧团建学生登录入口官网,网页设计模板如何使用源#xff1a;JNI中的内存管理 JNI 编程简介 JNI#xff0c;Java Native Interface#xff0c;是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code#xff1b;在 native code 中嵌入 Java 虚拟机调用 Java 的代码…源JNI中的内存管理 JNI 编程简介 JNIJava Native Interface是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code在 native code 中嵌入 Java 虚拟机调用 Java 的代码。 JNI 编程在软件开发中运用广泛其优势可以归结为以下几点 利用 native code 的平台相关性在平台相关的编程中彰显优势。对 native code 的代码重用。native code 底层操作更加高效。然而任何事物都具有两面性JNI 编程也同样如此。程序员在使用 JNI 时应当认识到 JNI 编程中如下的几点弊端扬长避短才可以写出更加完善、高性能的代码 从 Java 环境到 native code 的上下文切换耗时、低效。JNI 编程如果操作不当可能引起 Java 虚拟机的崩溃。JNI 编程如果操作不当可能引起内存泄漏。回页首 JAVA 中的内存泄漏 JAVA 编程中的内存泄漏从泄漏的内存位置角度可以分为两种JVM 中 Java Heap 的内存泄漏JVM 内存中 native memory 的内存泄漏。 Java Heap 的内存泄漏 Java 对象存储在 JVM 进程空间中的 Java Heap 中Java Heap 可以在 JVM 运行过程中动态变化。如果 Java 对象越来越多占据 Java Heap 的空间也越来越大JVM 会在运行时扩充 Java Heap 的容量。如果 Java Heap 容量扩充到上限并且在 GC 后仍然没有足够空间分配新的 Java 对象便会抛出 out of memory 异常导致 JVM 进程崩溃。 Java Heap 中 out of memory 异常的出现有两种原因——①程序过于庞大致使过多 Java 对象的同时存在②程序编写的错误导致 Java Heap 内存泄漏。 多种原因可能导致 Java Heap 内存泄漏。JNI 编程错误也可能导致 Java Heap 的内存泄漏。 JVM 中 native memory 的内存泄漏 从操作系统角度看JVM 在运行时和其它进程没有本质区别。在系统级别上它们具有同样的调度机制同样的内存分配方式同样的内存格局。 JVM 进程空间中Java Heap 以外的内存空间称为 JVM 的 native memory。进程的很多资源都是存储在 JVM 的 native memory 中例如载入的代码映像线程的堆栈线程的管理控制块JVM 的静态数据、全局数据等等。也包括 JNI 程序中 native code 分配到的资源。 在 JVM 运行中多数进程资源从 native memory 中动态分配。当越来越多的资源在 native memory 中分配占据越来越多 native memory 空间并且达到 native memory 上限时JVM 会抛出异常使 JVM 进程异常退出。而此时 Java Heap 往往还没有达到上限。 多种原因可能导致 JVM 的 native memory 内存泄漏。例如 JVM 在运行中过多的线程被创建并且在同时运行。JVM 为线程分配的资源就可能耗尽 native memory 的容量。 JNI 编程错误也可能导致 native memory 的内存泄漏。对这个话题的讨论是本文的重点。 回页首 JNI 编程中明显的内存泄漏 JNI 编程实现了 native code 和 Java 程序的交互因此 JNI 代码编程既遵循 native code 编程语言的编程规则同时也遵守 JNI 编程的文档规范。在内存管理方面native code 编程语言本身的内存管理机制依然要遵循同时也要考虑 JNI 编程的内存管理。 本章简单概括 JNI 编程中显而易见的内存泄漏。从 native code 编程语言自身的内存管理和 JNI 规范附加的内存管理两方面进行阐述。 Native Code 本身的内存泄漏 JNI 编程首先是一门具体的编程语言或者 C 语言或者 C或者汇编或者其它 native 的编程语言。每门编程语言环境都实现了自身的内存管理机制。因此JNI 程序开发者要遵循 native 语言本身的内存管理机制避免造成内存泄漏。以 C 语言为例当用 malloc() 在进程堆中动态分配内存时JNI 程序在使用完后应当调用 free() 将内存释放。总之所有在 native 语言编程中应当注意的内存泄漏规则在 JNI 编程中依然适应。 Native 语言本身引入的内存泄漏会造成 native memory 的内存严重情况下会造成 native memory 的 out of memory。 Global Reference 引入的内存泄漏 JNI 编程还要同时遵循 JNI 的规范标准JVM 附加了 JNI 编程特有的内存管理机制。 JNI 中的 Local Reference 只在 native method 执行时存在当 native method 执行完后自动失效。这种自动失效使得对 Local Reference 的使用相对简单native method 执行完后它们所引用的 Java 对象的 reference count 会相应减 1。不会造成 Java Heap 中 Java 对象的内存泄漏。 而 Global Reference 对 Java 对象的引用一直有效因此它们引用的 Java 对象会一直存在 Java Heap 中。程序员在使用 Global Reference 时需要仔细维护对 Global Reference 的使用。如果一定要使用 Global Reference务必确保在不用的时候删除。就像在 C 语言中调用 malloc() 动态分配一块内存之后调用 free() 释放一样。否则Global Reference  引用的 Java 对象将永远停留在 Java Heap 中造成 Java Heap 的内存泄漏。 回页首 JNI 编程中潜在的内存泄漏——对 LocalReference 的深入理解 Local Reference 在 native method 执行完成后会自动被释放似乎不会造成任何的内存泄漏。但这是错误的。对 Local Reference 的理解不够会造成潜在的内存泄漏。 本章重点阐述 Local Reference 使用不当可能引发的内存泄漏。引入两个错误实例也是 JNI 程序员容易忽视的错误在此基础上介绍 Local Reference 表对比 native method 中的局部变量和 JNI Local Reference 的不同使读者深入理解 JNI Local Reference 的实质最后为 JNI 程序员提出应该如何正确合理使用 JNI Local Reference以避免内存泄漏。 错误实例 1 在某些情况下我们可能需要在 native method 里面创建大量的 JNI Local Reference。这样可能导致 native memory 的内存泄漏如果在 native method 返回之前 native memory 已经被用光就会导致 native memory 的 out of memory。 在代码清单 1 里我们循环执行 count 次JNI function NewStringUTF() 在每次循环中从 Java Heap 中创建一个 String 对象str 是 Java Heap 传给 JNI native method 的 Local Reference每次循环中新创建的 String 对象覆盖上次循环中 str 的内容。str 似乎一直在引用到一个 String 对象。整个运行过程中我们看似只创建一个 Local Reference。 执行代码清单 1 的程序第一部分为 Java 代码nativeMethod(int i) 中输入参数设定循环的次数。第二部分为 JNI 代码用 C 语言实现了 nativeMethod(int i)。 清单 1. Local Reference 引发内存泄漏Java 代码部分  class TestLocalReference {  private native void nativeMethod(int i);  public static void main(String args[]) {          TestLocalReference c new TestLocalReference();          //call the jni native method          c.nativeMethod(1000000);  }    static {  //load the jni library  System.loadLibrary(StaticMethodCall);  }  }  JNI 代码nativeMethod(int i) 的 C 语言实现  #includestdio.h  #includejni.h  #includeTestLocalReference.h  JNIEXPORT void JNICALL Java_TestLocalReference_nativeMethod  (JNIEnv * env, jobject obj, jint count)  {  jint i 0;  jstring str;  for(; icount; i)          str (*env)-NewStringUTF(env, 0);  } 运行结果  JVMCI161: FATAL ERROR in native method: Out of memory when expanding  local ref table beyond capacity  at TestLocalReference.nativeMethod(Native Method)  at TestLocalReference.main(TestLocalReference.java:9)   运行结果证明JVM 运行异常终止原因是创建了过多的 Local Reference从而导致 out of memory。实际上nativeMethod 在运行中创建了越来越多的 JNI Local Reference而不是看似的始终只有一个。过多的 Local Reference导致了 JNI 内部的 JNI Local Reference 表内存溢出。 错误实例 2 实例 2 是实例 1 的变种Java 代码未作修改但是 nativeMethod(int i) 的 C 语言实现稍作修改。在 JNI 的 native method 中实现的 utility 函数中创建 Java 的 String 对象。utility 函数只建立一个 String 对象返回给调用函数但是 utility 函数对调用者的使用情况是未知的每个函数都可能调用它并且同一函数可能调用它多次。在实例 2 中nativeMethod  在循环中调用 count 次utility 函数在创建一个 String 对象后即返回并且会有一个退栈过程似乎所创建的 Local Reference 会在退栈时被删除掉所以应该不会有很多 Local Reference 被创建。实际运行结果并非如此。 清单 2. Local Reference 引发内存泄漏Java 代码部分参考实例 1未做任何修改。 JNI 代码nativeMethod(int i) 的 C 语言实现  #includestdio.h  #includejni.h  #includeTestLocalReference.h  jstring CreateStringUTF(JNIEnv * env)  {  return (*env)-NewStringUTF(env, 0);  }  JNIEXPORT void JNICALL Java_TestLocalReference_nativeMethod  (JNIEnv * env, jobject obj, jint count)  {  jint i 0;  for(; icount; i)  {          str CreateStringUTF(env);  }  } 运行结果  JVMCI161: FATAL ERROR in native method: Out of memory when expanding local ref  table beyond  capacity  at TestLocalReference.nativeMethod(Native Method)  at TestLocalReference.main(TestLocalReference.java:9) 运行结果证明实例 2 的结果与实例 1 的完全相同。过多的 Local Reference 被创建仍然导致了 JNI 内部的 JNI Local Reference 表内存溢出。实际上在 utility 函数 CreateStringUTF(JNIEnv * env) 执行完成后的退栈过程中创建的 Local Reference 并没有像 native code 中的局部变量那样被删除而是继续在 Local Reference 表中存在并且有效。Local Reference 和局部变量有着本质的区别。 Local Reference 深层解析 Java JNI 的文档规范只描述了 JNI Local Reference 是什么存在的目的以及应该怎么使用 Local Reference开放的接口规范。但是对 Java 虚拟机中 JNI Local Reference 的实现并没有约束不同的 Java 虚拟机有不同的实现机制。这样的好处是不依赖于具体的 JVM 实现有好的可移植性并且开发简单规定了“应该怎么做、怎么用”。但是弊端是初级开发者往往看不到本质“不知道为什么这样做”。对  Local Reference 没有深层的理解就会在编程过程中无意识的犯错。 Local Reference 和 Local Reference 表 理解 Local Reference 表的存在是理解 JNI Local Reference 的关键。 JNI Local Reference 的生命期是在 native method 的执行期从 Java 程序切换到 native code 环境时开始创建或者在 native method 执行时调用 JNI function 创建在 native method 执行完毕切换回 Java 程序时所有 JNI Local Reference 被删除生命期结束调用 JNI function 可以提前结束其生命期。 实际上每当线程从 Java 环境切换到 native code 上下文时J2NJVM 会分配一块内存创建一个 Local Reference 表这个表用来存放本次 native method 执行中创建的所有的 Local Reference。每当在 native code 中引用到一个 Java 对象时JVM 就会在这个表中创建一个 Local Reference。比如实例 1 中我们调用 NewStringUTF() 在 Java Heap 中创建一个 String 对象后在 Local Reference 表中就会相应新增一个 Local Reference。 图 1. Local Reference 表、Local Reference 和 Java 对象的关系   图 1 中 ⑴运行 native method 的线程的堆栈记录着 Local Reference 表的内存位置指针 p。 ⑵ Local Reference 表中存放 JNI Local Reference实现 Local Reference 到 Java 对象的映射。 ⑶ native method 代码间接访问 Java 对象java obj1java obj2。通过指针 p 定位相应的 Local Reference 的位置然后通过相应的 Local Reference 映射到 Java 对象。 ⑷当 native method 引用一个 Java 对象时会在 Local Reference 表中创建一个新 Local Reference。在 Local Reference 结构中写入内容实现 Local Reference 到 Java 对象的映射。 ⑸ native method 调用 DeleteLocalRef() 释放某个 JNI Local Reference 时首先通过指针 p 定位相应的 Local Reference 在 Local Ref 表中的位置然后从 Local Ref 表中删除该 Local Reference也就取消了对相应 Java 对象的引用Ref count 减 1。 ⑹当越来越多的 Local Reference 被创建这些 Local Reference 会在 Local Ref 表中占据越来越多内存。当 Local Reference 太多以至于 Local Ref 表的空间被用光JVM 会抛出异常从而导致 JVM 的崩溃。 Local Ref 不是 native code 的局部变量 很多人会误将 JNI 中的 Local Reference 理解为 Native Code 的局部变量。这是错误的。 Native Code 的局部变量和 Local Reference 是完全不同的区别可以总结为 ⑴局部变量存储在线程堆栈中而 Local Reference 存储在 Local Ref 表中。 ⑵局部变量在函数退栈后被删除而 Local Reference 在调用 DeleteLocalRef() 后才会从 Local Ref 表中删除并且失效或者在整个 Native Method 执行结束后被删除。 ⑶可以在代码中直接访问局部变量而 Local Reference 的内容无法在代码中直接访问必须通过 JNI function 间接访问。JNI function 实现了对 Local Reference 的间接访问JNI function 的内部实现依赖于具体 JVM。 代码清单 1 中 str (*env)-NewStringUTF(env, 0); str 是 jstring 类型的局部变量。Local Ref 表中会新创建一个 Local Reference引用到 NewStringUTF(env, 0) 在 Java Heap 中新建的 String 对象。如图 2 所示 图 2. str 间接引用 string 对象   图 2 中str 是局部变量在 native method 堆栈中。Local Ref3 是新创建的 Local Reference在 Local Ref 表中引用新创建的 String 对象。JNI 通过 str 和指针 p 间接定位 Local Ref3但 p 和 Local Ref3 对 JNI 程序员不可见。 Local Reference 导致内存泄漏 在以上论述基础上我们通过分析错误实例 1 和实例 2来分析 Local Reference 可能导致的内存泄漏加深对 Local Reference 的深层理解。 分析错误实例 1 局部变量 str 在每次循环中都被重新赋值间接指向最新创建的 Local Reference前面创建的 Local Reference 一直保留在 Local Ref 表中。 在实例 1 执行完第 i 次循环后内存布局如图 3 图 3. 执行 i 次循环后的内存布局   继续执行完第 i1 次循环后内存布局发生变化如图 4 图 4. 执行 i1 次循环后的内存布局   图 4 中局部变量 str 被赋新值间接指向了 Local Ref i1。在 native method 运行过程中我们已经无法释放 Local Ref i 占用的内存以及 Local Ref i 所引用的第 i 个 string 对象所占据的 Java Heap 内存。所以native memory 中 Local Ref i 被泄漏Java Heap 中创建的第 i 个 string 对象被泄漏了。 也就是说在循环中前面创建的所有 i 个 Local Reference 都泄漏了 native memory 的内存创建的所有 i 个 string 对象都泄漏了 Java Heap 的内存。 直到 native memory 执行完毕返回到 Java 程序时N2J这些泄漏的内存才会被释放但是 Local Reference 表所分配到的内存往往很小在很多情况下 N2J 之前可能已经引发严重内存泄漏导致 Local Reference 表的内存耗尽使 JVM 崩溃例如错误实例 1。 分析错误实例 2 实例 2 与实例 1 相似虽然每次循环中调用工具函数 CreateStringUTF(env) 来创建对象但是在 CreateStringUTF(env) 返回退栈过程中只是局部变量被删除而每次调用创建的 Local Reference 仍然存在 Local Ref 表中并且有效引用到每个新创建的 string 对象。str 局部变量在每次循环中被赋新值。 这样的内存泄漏是潜在的但是这样的错误在 JNI 程序员编程过程中却经常出现。通常情况在触发 out of memory 之前native method 已经执行完毕切换回 Java 环境所有 Local Reference 被删除问题也就没有显露出来。但是某些情况下就会引发 out of memory导致实例 1 和实例 2 中的 JVM 崩溃。 控制 Local Reference 生命期 因此在 JNI 编程时正确控制 JNI Local Reference 的生命期。如果需要创建过多的 Local Reference那么在对被引用的 Java 对象操作结束后需要调用 JNI function如 DeleteLocalRef()及时将 JNI Local Reference 从 Local Ref 表中删除以避免潜在的内存泄漏。 回页首 总结 本文阐述了 JNI 编程可能引发的内存泄漏JNI 编程既可能引发 Java Heap 的内存泄漏也可能引发 native memory 的内存泄漏严重的情况可能使 JVM 运行异常终止。JNI 软件开发人员在编程中应当考虑以下几点避免内存泄漏 native code 本身的内存管理机制依然要遵循。使用 Global reference 时当 native code 不再需要访问 Global reference 时应当调用 JNI 函数 DeleteGlobalRef() 删除 Global reference 和它引用的 Java 对象。Global reference 管理不当会导致 Java Heap 的内存泄漏。透彻理解 Local reference区分 Local reference 和 native code 的局部变量避免混淆两者所引起的 native memory 的内存泄漏。使用 Local reference 时如果 Local reference 引用了大的 Java 对象当不再需要访问 Local reference 时应当调用 JNI 函数 DeleteLocalRef() 删除 Local reference从而也断开对 Java 对象的引用。这样可以避免 Java Heap 的 out of memory。使用 Local reference 时如果在 native method 执行期间会创建大量的 Local reference当不再需要访问 Local reference 时应当调用 JNI 函数 DeleteLocalRef() 删除 Local reference。Local reference 表空间有限这样可以避免 Local reference 表的内存溢出避免 native memory 的 out of memory。严格遵循 Java JNI 规范书中的使用规则。http://www.ibm.com/developerworks/cn/java/j-lo-jnileak/index.html?cadrs- 自己总结了解几个概念 1. 局部变量和Local Ref的概念一定要清晰。要知道native method运行的内存空间是由虚拟机所分配。当native method执行完成。这部份内存就会自动被回收。当然包括指向 Java Heap的内存。 2. Golbal Ref所引用的内存必须要手动调用DeleteGolbalRef来释放。如果不释放。就会造成Java Heap memory leak. 3. 当某个native method 中使用的Local Ref很多的时候。会造成 Local Ref table表的内存溢出。或者Java Heap内存占用过多引起JVM崩溃。所以对于Local Ref的使用。推荐 提前调用DeleteLocalRef。自己定义一个标准就是凡是带有New的内容都要主动调用Delete。其他可以等待其生命其结束后由GC回收 4. 其他内存管理遵循 C/C自己内存管理机制。凡用到的堆空间。全部自己手动释放  转载于:https://www.cnblogs.com/LittleTiger/p/4555496.html
http://wiki.neutronadmin.com/news/101493/

相关文章:

  • 宽屏大气企业网站源码有没有专做自驾游的网站
  • 网站建设长期待摊费用如何建设高校网站
  • 专业微网站电话网站建设收费标准教程
  • 网站开发网校市政浙江建设培训中心网站
  • 网站开发跟app开发的差别钢材网站模板
  • 好点子网站建设wordpress部署到tomcat
  • 站长之家ping深圳公司网站如何设计
  • 网站建设的经验之谈简述网站的建站具体流程
  • 企业电子商务网站建设规划方案广告公司业务推广
  • 建设营销网站要什么wordpress商用收费不
  • 网站的黏度广州海珠区房价
  • 三亚本地网站建设校园内部网站建设方案
  • 石家庄做网站比较好的公司做寻亲网站的理由
  • 网站所有者是什么意思龙岗企业网站制作公司
  • mui做wap网站网站营销seo
  • 海宁做网站的公司北京建设工程信息网人员库里的人怎么删除
  • 找产品代理去哪个网站wordpress上传中文图片
  • 如何建立自己的网站平台网站模板购买 优帮云
  • 什么网站可以做私房菜外卖昆山网站建设多少钱
  • alexa的网站排名主要分为哪两种西安网站排名哪家公司好
  • 站内关键词排名软件西安最新传染病
  • 手机qq查看网站源码奉化seo页面优化外包
  • 网站建设 石景山滁州seo优化
  • 怎么把网站做成自适应网址如何下载视频
  • 网站建设 请示密云建设网站公司
  • 网站的建设步骤网站手机版如何制作
  • 长春网站排名公司网站迭代
  • ECMS做的网站上海专业网站建设排行
  • 网站建设动态代码巴楚网站建设
  • 网站的建设哪个好深圳代理记账行业协会