深入理解JVM

深入理解JVM读书笔记


走近java

  1. Sun官方定义的java技术体系包括:java程序设计语言,各种硬件平台上的java虚拟机,class文件格式,Java API类库,来自商业机构和开源社区的第三方Java类库。
  2. JDK由Java程序设计语言,Java虚拟机,Java API类库这三部分组成,是支持Java程序开发的最小环境。

深入理解JVM

  1. Java技术平台:

Java Card:支持一些Java小程序(Applets)运行在小内存设备上的平台。

Java ME(Micro Edition):支持Java长须运行在移动终端(手机,PDA)上的平台。

Java SE(Standard Edition):支持面向桌面级应用的Java平台,提供了Java完整的核心API。

Java EE(Enterprise Edition):支持使用多层架构的企业应用的Java平台。

自动内存管理机制

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

运行时数据区域

  • Java虚拟机所管理的内存结构如下所示:

深入理解JVM

  • 程序计数器(线程私有)

作用:记录当前线程所执行的字节码的行号。字节码解释器工作的时候就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

意义:JVM的多线程是通过线程轮流切换并分配处理器来实现的。一个处理器只会执行一条线程中的指令,每个线程都有独立私有的程序计数器。

存储内容:当执行的是一个Java方法时,程序计数器中记录的是正在执行的线程的虚拟机字节码指令地址;当执行的是一个本地(native)方法时,程序计数器中的值为空。

异常:次区域是唯一一个在JVM上不会发生内存溢出异常(OutOfMemoryError)的区域。

  • 虚拟机栈(线程私有)

作用:描述Java方法执行的内存模型。每个方法在执行的同事都会开辟一段内存区域用于存放方法运行时所需的数据,成为栈帧,一个栈帧包含:局部变量表,操作数栈,动态链接,方法出口等信息。

意义:JVM是基于栈的,所以每个方法从调用到执行结束,就对应着一个栈帧在虚拟机栈中入栈和出栈的整个过程。

存储内容局部变量表(编译期可知的各种基本数据类型、引用类型和指向一条字节码指令的returnAddress类型)、操作数栈、动态链接、方法出口等信息。
值得注意的是:局部变量表所需的内存空间在编译期间完成分配。在方法运行的阶段是不会改变局部变量表的大小的。

异常:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出*Error异常。
如果在动态扩展内存的时候无法申请到足够的内存,就会抛出OutOfMemoryError异常。

  • Java堆(线程共享)

作用:所有线程共享一块内存区域,在虚拟机开启的时候创建。

意义:1、存储对象实例,更好地分配内存。
2、垃圾回收(GC)。堆是垃圾收集器管理的主要区域。更好地回收内存。

存储内容:存放对象实例,几乎所有的对象实例都在这里进行分配。堆可以处于物理上不连续的内存空间,只要逻辑上是连续的就可以。
值得注意的是:在JIT编译器等技术的发展下,所有对象都在堆上进行分配已变得不那么绝对。有些对象实例也可以分配在栈中。

异常:实现堆可以是固定大小的,也可以通过设置配置文件设置该为可扩展的。
如果堆上没有内存进行分配,并无法进行扩展时,将会抛出OutOfMemoryError异常。

  • 方法区(线程共享)

作用:用于存储运行时常量池、已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

意义:对运行时常量池、常量、静态变量等数据做出了规定。

存储内容:运行时常量池(具有动态性)、已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

异常:当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

hotspot虚拟机对象探秘