Java内存分析 --- 虚拟机运行时数据区

来源:互联网 发布:陕西广电网络吧 编辑:程序博客网 时间:2024/05/19 23:01
Java内存分析:虚拟机运行时数据区1)程序计数器(Program Counter Register):可以看做当前线程所执行的字节码的行号指示器工作:通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。说明:程序计数器是线程私有的。每条线程都需要有一个独立的程序计数器,各条线程间的计数器互不影响,独立储存。举例:如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是native方法,这个计数器值则为空。2)Java虚拟机栈:描述的是Java方法执行的内存模型。工作:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于储存局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈道出栈的过程。说明:1)Java虚拟机栈是线程私有的,它的生命周期与线程相同。2)一般人们所说的“栈”就是指虚拟机栈,或者指虚拟机栈中局部变量表部分局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、int..)、对象引用等异常:虚拟机栈中规定了两种异常状况:1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;2)如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可以动态扩展),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常3)本地方法栈(Native Method Stack):为虚拟机使用到的Native方法服务。说明:与虚拟机栈的区别:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。Sun HotSpot虚拟机直接就把本地方法栈和虚拟机栈合二为一。异常:与虚拟机栈中规定的异常相同。4)Java堆:是被所有线程共享的一块内存区域,在虚拟机启动时创建。唯一的目的就是存放对象实例现在收集器基本都采用分代收集算法Java堆分为新生代、老年代新生代(Young generation)结构:Eden空间、From Survivor空间、To Survivor空间特点:新生代中大部分的对象是“朝生夕死”的,每次垃圾收集时都发现有大批对象死去,只有少量存活老年代(Tenured generation)特点:老年代中的对象存活率高、没有额外空间对它进行分配担保。注:新生代GC(Minor GC)、老年代GC(Full GC、Major GC)5)方法区(永久代:Permanent Generation):用于储存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。说明:1)与Java堆一样,方法区是各个线程共享的内存区域。2)Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆)运行时常量池:是方法区的一部分方法区的回收:主要回收:废弃的常量、无用的类废弃常量:没有任何引用关联着的常量即废弃常量。无用的类:同时满足以下3个条件的类1)该类所有的实例都已经被回收,也就是说Java堆中不存在该类的任何引用。2)加载该类的ClassLoader已经被回收3)该类对应的Class对象没有再任何地方被引用,无法在任何地方通过反射访问该类的方法。注:满足条件的类是否会被回收,由虚拟机设定:由 -Xnoclassgc 参数进行控制。重要:在大量使用反射、动态代理(jdk动态代理、cglib动态代理等)、动态生成jsp 的场景中都需要虚拟机具备类卸载功能,以保证方法区不会溢出。

0 0