小白一枚,最近在看深入理解java虚拟机2这本书,怕看过之后就忘了,看一节然后写一片博客消化消化,加深印象与理解。有理解错误的地方还望指出。
Java虚拟机主要分为方法区,虚拟机栈,本地方法栈,程序计数器,堆。其中方法区与堆是线程共享区域;虚拟机栈,本地方法栈,程序计数器是线程私有区域。
方法区主要存放加载的类信息,常量,静态常量,即时编译器编译后的代码等,也有人称之为永久代,二者并非一样,或者说是HotSpot虚拟机用永久代实现了虚拟机的方法区,为了方便HotSpot垃圾收集器可以向管理java堆一样去管理这块区域。
虚拟机栈是线程私有的,在java方法执行的时候会创建一个栈帧,用来存放局部变量表,动态链接,操作数栈,方法出口等信息。其中局部变量表存放8个基本数据类型与对象的引用。64位长度的long类型与double会占用2个局部变量空间,其余的占用1个。在编译期间,方法需要分配的局部变量空间是确定的。
本地方法栈与虚拟机栈非常类似,只不过虚拟机栈是为java方法服务,本地方法栈是为Native方法服务。
程序计数器是线程私有的,用来记录当前线程正在执行的虚拟机字节码指令地址,如果正在执行Native方法,计数器值则为undefined。
堆是虚拟机所管理的最大区域,所有的线程共享,用来存放对象实例。现在的垃圾收集器基本采用了分代收集算法,还可以细分新生代和老年代,其中新生代还可以细分为Eden,From Survivor, To Survivor三个区域。虚拟机提供了-XX:PretenureSizeThreshold参数,可以设置当对象占用空间的大小超过这个值,将直接在老年代创建,避免来回复制。