JVM内存区域

JVM整体示意图:

JVM内存区域_第1张图片 JVM内存区域

程序计数器:

  • 程序计数器是一块较小的内存空间,它可以看作是当前线程执行行的字节码的行号指示器(goto可以看作是按照这个行号跳转);
  • 程序计数器处于线程独占区,每一个线程都有一份;
  • 如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined;
  • 此区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

 Java虚拟机栈:

  • 虚拟机栈描述的是Java方法执行的动态内存模型
  • 栈帧
    • 每个方法执行,都会创建一个栈帧,这个栈帧伴随着方法从创建到执行完成;
    • 用于存储局部变量表,操作数栈,动态链接,方法出口等;
  •  局部变量表
    • 存放编译器可知的各种基本数据类型,引用类型,returnAddress类型;
    • 局部变量表的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在栈帧中分配多少内存是固定的,在方法运行期间是不会改变局部变量表的大小的;
    • 局部变量表中存放的是一个对象的引用,所以说创建对象也不会改变它的大小(引用是一个地址)
  • 虚拟机栈的大小
    • 会抛出StackOverflowError
    • 不限定虚拟机栈的大小会随着方法的入栈最终导致OutOfMemoryError

 本地方法栈:

  • 本地方法栈和虚拟机栈是很类似的;
  • 区别
    • Java虚拟机栈是为Java方法来服务的;
    • 本地方法栈是为native方法来服务的;
  • 它也一样有栈帧、局部变量表这些东西 ;

 Java堆:

  • Java堆就是用来存储对象实例的;
  • 也是垃圾收集器管理的主要区域;
  • 分为新生代、老年代等;
  • -Xmx -Xms指定堆内存大小;

 方法区:

  • JVM只有只有一个方法区,被所有线程共享;
  • 方法区实际上也是一块堆,只是用来存储类,常量相关的信息;
  • 用来存放程序中永远不变或唯一的内容(类信息[Class对象]、静态变量、字符串常量等)
  • 方法虚拟机存储加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;
    • 类的版本
    • 字段
    • 方法
    • 接口
  •  方法区和永久代
  • 垃圾回收在方法区的行为很少,回收效率低(常量池的回收,类的卸载等)
  • 运行时常量池
    • 运行时常量池的数据结构相当于一个HashSet,无序,不重复的
    • 两个相同的字符串引用记录同一个地址
    • String如果实在堆内存new出来的,调用string.intern()方法,如果常量池中有equals(s)的字符串,则返回该地址,如果常量池中没有,则在常量池中创建一个,并返回该地址

 

 

你可能感兴趣的:(JVM)