内存模型

如果了解java虚拟机更系统的操作。请阅读 Charlie Hunt , Binu John著《java性能优化权威指南》,James Gosling,Java之父、Steve Wilson,Oracle公司工程副总裁写序。

Java虚拟机运行时数据区:

  1. PC寄存器(程序计数器):program counter线程私有的较小的内存空间,保存当前线程所执行的字节码指令地址。在虚拟机概念模型里:字节码解释器工作是通过改变计数器的值来选取下一条需要执行的字节码指令。Native方法,计数器值为undefined。
  2. JAVA虚拟机栈:线程私有。保存局部变量与没有算好的结果。Java栈对应操作系统实际内存的堆中分配。每个方法执行时都会创建一个栈帧。方法从调用到执行完的过程对应栈帧在虚拟机栈中入栈出栈的过程。新线程请求容量(栈深度)超过允许会抛出StackOverflowError异常,如果没有足够内存分配会抛出OutOfMemoryError异常。
  1. 本地方法栈:线程私有。对应实际的栈。与JAVA栈类似,本地方法栈用于给Native方法服务,异常情况类似。
  2. :线程共享。保存对象实例和数组,垃圾回收器管理的主要区域。分为新生代和老年代。新生代分为Eden、From Survivor、To Survivor。JVM在内存新生代Eden Space中开辟了一小块线程私有的区域,称作TLAB(Thread-local allocation buffer)。默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。老年代:JDK1.8之后的字符串常量池,在老年代。
  3. 方法区:即永久代,线程共享。保存类结构信息:运行时常量池、字段、方法数据、构造函数和普通方法的字节码,还包括类、实例、接口初始化时用到的特殊方法。可以回收一些废弃常量和无用的类。
  1. 直接内存:通过java.nio.ByteBuffer.allocateDirect(capacity);来直接操作堆外内存。避免了在java堆和Native堆中来回复制数据。

posted @ 2017-07-08 20:29  jiumao  阅读(100)  评论(0编辑  收藏  举报