0
点赞
收藏
分享

微信扫一扫

3分钟速读原著《深入理解Java虚拟机》(二)


1.JVM虚拟机


  • 1.1 Sun Classic/Exact VM:世界上的第一款商用Java虚拟机
  • 1.2 Sun HotSpot VM:目前的Sun JDK和Open JDK中所自带的虚拟机
  • 1.3 Sun Mobile-Embedded VM/Meta-Circular :针对移动和嵌入式市场
  • 1.4 BEA JRockit/IBM J9 VM 号称是世界上最快的JVM 与HotSpot VM并驾齐驱
  • 1.5 Azul VM/BEA Liquid VM 在特定硬件平台专有的虚拟机
  • 1.6 Apache Harmony/Goole Andriod Dalvik VM 属于自带组件的虚拟机,不算是JAVA的虚拟机
  • 1.7 Microsoft JVM 微软曾是Java技术的支持者,自己开发了一套JVM,被Sun公司告侵权后放弃了该JVM的持续开发

2.Java技术的未来


  • 2.1 模块化:拆分成各个API和对应组件,做到高内聚和低耦合并行
  • 2.2 混合语言
  • 2.3 多核并行:

  • ①JDK1.5的java.util.concurrent
  • ②JDK1.7的java.util.concurrent.forkjoin,采用Fork/Join模式
  • ③JDK1.8的Lambda,提供了函数式编程,函数式编程是天然的适合并行运行的

  • 2.4 丰富语法:JDK1.5加入了自动装箱,泛型,动态注解(自定义注解),枚举可变长参数,遍历循环等语法,提升了Java的精确性和易用性
  • 2.5 64位虚拟机:JDK1.6之前64位的JVM性能比32位的低一些,在JDK1.6的时候增加了普通对象的指针压缩功能-XX?+UseCompressedOops,可以提升一些性能,但是一般情况下并不建议使用

3.Java内存区域与内存溢出异常

对于C/C++来说,每个堆内存的new都需要delete/free操作,对于Java来说内存管理已经交给JVM,好处是不用处理内存,坏处是容易出现OOM问题


  • 3.1 程序计数器:

  • ①内存空间较小,当前线程所执行的字节码的行号指示器,不同的虚拟机通过不同的方式去实现,字节码解释器工作的时候通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要根据这个计数器来完成
  • ②每条线程有自己的程序计数器,互不干扰
  • ③如果线程正在执行的是一个Java方法,那么这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是Native方法,则计数器的值为空(Undefined),此内存区域是唯一一个在Java虚拟机规范中没有规定任何OOM情况的的区域

  • 3.2 Java虚拟机栈

  • ①每条线程独有一份,包含局部变量表,操作数栈,动态链接,方法出口灯
  • ②局部变量表存放基本数据类型和引用类型的地址值,最大为32位,long和double为64位,则储存两个局部变量空间.
  • ③两种异常情况:线程请求的栈深度大于虚拟机所允许的深度,将抛出SO异常(栈溢出),如果虚拟机栈可以动态拓展,拓展时无法申请到足够的内存,就会抛出OOM

  • 3.3 本地方法栈
  • ①作用于虚拟机栈作用相似,区别是虚拟机栈是针对Java方法,本地方法栈针对Native方法
  • 3.4 Java堆

  • ①用于存储对象和数组,所有线程共享的区域
  • ②分成Java堆和Native堆,Java堆是Java方法当中new出来的对象实例存储,Native堆则是Native方法当中产生的实例对象
  • ③GC管理的主要区域,故称为GC堆,(英文名称为Garbage Collected Heap ,幸好国美没有翻译成’垃圾堆’),现存的GC算法都是分代收集,可以分成新生代和年老代,以及永久代,永久代类似方法区当中的常量,在HotSpot VM当中永久代与方法区的设计相同,后续再进行赘述
  • ④堆空间可以通过配置-Xmx 和-Xms 启动内存和运行内存来控制其大小,如果对中内有内存完成实例分配,并且堆也无法再拓展时,即会产生OOM

  • 3.5 方法区

  • ①各个线程共享的内存区域
  • ②在HotSpot VM当中设计与堆当中的永久代类似,可以选择不被GC回收
  • ③用于存储已经被JVM加载的类/常量/静态变量/即时编译后的代码等数据,
  • ④方法区中的常量池用于存储final修饰的常量,这部分的GC回收比较差,类型的卸载条件相对比较苛刻,曾经出现低版本的HotSpot VM对此区域未完全回收而导致内存泄漏OOM



备注:并不是存储所有的类/常量/静态变量/编译的代码,这里存储的是JVM根据需要选择出来的结果



  • 3.6 运行时常量池
  • ①方法区当中的一部分,已在上面赘述
  • 3.7 直接内存
  • ①JDK1.4当中加入了NIO,可以使用Native函数库直接分配堆外内存,然后通过存储在Java堆当中的DirectByteBuffer对象作为这块内存的引用进行操作,在一些需要重复调用到Java方法和Native方法的场景当中,减少了Java堆和Native堆中来回复制数据的性能消耗


举报

相关推荐

0 条评论