1.1 程序计数器
Ø 用途:
每个线程都有一个程序计数器,用于记录该线程当前所执行字节码的行号。
natice方法由于不是java方法,因此当执行native方法时计数器为空。
Ø 创建时间:
线程启动的同时
Ø 销毁时间:
线程销毁的同时
Ø 特点:
线程私有,唯一一个java虚拟机规范中没有规定OutOfMemeryError的内存区域。生命周期与线程相同。
1.2 虚拟机栈
Ø 用途:
每个方法执行的时都会创建一个栈帧用于存储局部变量表(顾名思义,就是存储该方法的局部变量对象的引用),操作数栈,动态链接,方法出口等信息。每一个方法从执行到完成就对应一个栈帧在虚拟机栈从入栈到出栈的过程。
Ø 创建时间:
线程启动的同时
Ø 销毁时间:
线程销毁的同时
Ø 特点:
线程私有。每一个方法从执行到完成就对应一个栈帧在虚拟机栈从入栈到出栈的过程。虚拟机栈服务于java方法。
Ø 溢出异常:
StackOverflowError:当线程请求的栈深度大于虚拟机所允许的深度时,抛出该异常。
OutOfMemeoryError:如果虚拟机栈可以动态扩展,那么当动态扩展时无法申请到足够的内存,就会抛出该异常。
Ø 内存大小设置方式:-Xss
如-Xss256K: 就是设置每个线程的运行时栈的大小为 256K。
固定了栈内存大小后,当方法的局部变量表内容越多,栈帧越大,栈深度越小。
Ø 简单的栈帧出入栈模型:
1.3 本地方法栈
Ø 用途:
本地方法栈的作用与虚拟机栈的作用相似,但是本地方法栈是为虚拟机中使用到的Native方法服务的。
Ø 创建时间
线程启动的同时。
Ø 销毁时间
线程销毁的同时。
Ø 特点:
服务于Native方法。
Ø 溢出异常:
StackOverflowError:当线程请求的栈深度大于虚拟机所允许的深度时,抛出该异常。
OutOfMemeoryError:如果虚拟机栈可以动态扩展,那么当动态扩展时无法申请到足够的内存,就会抛出该异常。
1.4 java堆
Ø 用途:
用于存放对象。
Ø 创建时间:
虚拟机启动时。
Ø 销毁时间:
虚拟机销毁时。
Ø 特点:
1) 各线程共享;
2) 是垃圾收集器管理的主要区域。java堆可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。
Ø 溢出异常:
OutOfMemeoryError:如果在堆中没有完成实例分配,并且堆也无法再扩展时,将会抛出该异常。
Ø 内存大小设置方式:
-Xmx 设置最大堆内存。
-Xms 设置初始堆内存。
1.5方法区
Ø 用途:
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
Ø 创建时间
虚拟机启动时。
Ø 销毁时间
虚拟机销毁时。
Ø 特点:
所有线程共享。
HotSpot虚拟机1.8及以上版本,已将方法区从从永久代移出,取而代之使用的是元空间,元空间使用的是本地内存。
Ø 溢出异常:
OutOfMemeoryError:当方法区无法满足内存分配需求时,将抛出该异常。
Ø 参数设置
"-XX:MaxMetaspaceSize" (JDK8):指定类元数据区的最大内存大小;
"-XX:MetaspaceSize" (JDK8):MetaspaceSize表示metaspace首次使用不够而触发FGC的阈值;
"-Xnolassgc":关闭CLASS的垃圾回收功能,就是虚拟机加载的类,即便是不使用,没有实例也不会回收。
"-verbose:class"、"-XX:TraceClassLoading"、"-XX:TraceClassUnloading":查看类加载和卸载信息;
1.6运行时常量池
Ø 用途:
编译期生成的各种字面量和符号引用。
Ø 特点:
属于方法区中的一部分。
相对于Class文件的常量池,运行时常量池具有动态性,运行期间新的常量也会被放入池中。该特性被开发人员利用较多的是String类的intern()方法。