程序计数器能够理解为虚拟机下一次要执行的字节码位置,能够经过改变这个行号来实现循环,跳转等功能。线程私有。java
虚拟机栈是和线程生命周期一致,随线程生而生,为线程私有的区域。当咱们调用一个方法的时候,会建立一个栈帧(通俗理解成一个栈数组吧),方法里的基本数据类型(局部变量表)、操做数栈、动态链家、方法出口会入栈到这个数组里,当咱们离开这个方法的时候,就会出栈。算法
当栈深度大于虚拟机所容许的深度时候,抛出stackoverflow异常。(这个是虚拟机栈深度没法拓展时会触发)数组
当虚拟机容许栈深度能够拓展时,若是拓展时没法申请足够的内存空间,抛出OutOfMemoryError。优化
栈比堆速度快的缘由的解释:线程
1)栈是程序启动的时候,系统分好了给你的,你本身用,系统不干预。堆是用的时候才向系统申请的,用完了还回去,这个申请和交还的过程开销相对就比较大了。对象
2)栈是编译时分配空间,而堆是动态分配(运行时分配空间),因此栈的速度快。生命周期
基本和虚拟机栈同样,区别为:虚拟机栈是虚拟机使用java方法服务,而本地方法栈是虚拟机调用本地的native方法服务。内存
堆是内存里面最大的一块区域,咱们平时涉及到的new出来的对象几乎都放在这里(JIT的编译优化,使得有些对象能够不用存放在堆里) 。是垃圾回收的主要区域,也成为GC堆,堆里面由于垃圾回收算法,也细分红新生代和老年代(永久代是位于方法区,方法区虽然和堆很像,但通常称之为:non-heap即非堆)。虚拟机
用来存储加载类所用到的类信息、常量、静态变量等数据。Hotspot虚拟机通常会把方法区叫作“永久代”。称之为永久代主要缘由是垃圾回收的时候基本都是回收堆里面的,而在方法区通常不回收,要么就是回收的效果惨淡,所以俗称永久代。Hotspot1.7版本将常量池移出方法区了。编译
常量池是方法区的一部分,用来存放编译时生成的各类字面量和符号引用。String.intern()方法会先去常量池里面找,是否有这个字符,若是有,则返回这个字符的引用,若是没有则将这个字符放入常量池。