深入理解java虚拟机——读后笔记(一)(内存部分)

一、内存区域的划分(运行时数据区域)

  ①程序计数器:程序计数器是一块较小的内存区域,字节码解释器通过改变此计数器的值来选取下一条要执行的字节码指令,可以看成是当前线程执行字节码的行号指示器。线程执行时的分支、循环、跳转、异常处理、线程恢复等功能都依赖它。每条线程拥有独立的程序计数器,互不影响,独立储存。此区域没有OutOfMemory。

  ②Java虚拟机栈:虚拟机栈也是线程私有内存区域,生命周期和线程相同。每个方法在执行时都会创建一个栈帧,用于储存局部变量表操作数栈、动态链接、方法出口等信息,局部变量表中储存了编译时期可知的各种数据类型、引用类型、returnAddress(指向一条字节码指令地址)。局部变量表的大小在编译期完成分配,方法运行期间不会改变局部变量表的大小。如果线程请求的深度大于虚拟机所允许的深度,会抛出StackOverflowError,如果线程动态扩展时无法申请到足够的内存会抛出OutOfMemoryError。

  ③本地方法栈:本地方法栈是native方法运行时区域,也会抛出StackOverflowErroar和OutOfMemoryError异常。

  ④Java堆:堆是虚拟机中最大的一块内存区域,被所有线程共享。主要用来储存对象实例,GC的主要场所。可以细分为老年代、新生代(包括Eden区域、from survivor区、to survivor区域)。可通过-Xmx,-Xms设置堆大小,如果堆中内存不足以分配新的对象且无法扩展,则会抛出OutOfMemoryError异常

  ⑤方法区域(永久带):此区域是jdk1.7及以下才有的内存区域,jdk1.8移除了永久带,增加了“元空间”。方法区也是所有线程共享的内存区域,用于储存虚拟机已加载的类信息、常量、静态常量、即时编译器编译后的代码数据。

  ⑥运行时常量池:方法区的一部分,Class文件中的常量池存放的编译期生成的各种字面量和符号引用,将在类加载后进入方法区的运行时常量池存放。具备动态性,在运行期间也能将新的常量放入运行时常量池中。

  ⑦直接内存:并不是虚拟机运行时数据区域的一部分,NIO能使用Native方法直接分配堆外内存,通过一个储存在堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

猜你喜欢

转载自www.cnblogs.com/nubea/p/12083791.html