纲领
Java的运行时数据区为:
A. 方法区 -----------(线程共有)
B. 堆 -----------(线程共有)
C. 虚拟机栈 -----------(线程私有)
D. 本地方法栈-----------(线程私有)
E. 程序计数器-----------(线程私有)
注意:
A. 线程私有,也就是说每条线程都有一个C,D,E这样的区域,这样才能在各个线程运行时不受影响
B. 线程私有的数据区的生命周期与线程相同
虚拟机栈
该栈为虚拟机执行java方法(字节码)服务,每个方法在执行的时候都会同时创建一个栈帧,用来储存局部变量表(该表存放基本数据类型,对象引用类型等。其中lang,double占用2个局部变量空间,其余的各占一个),操作数栈,动态链接,方法出口等信息
其实,方法的执行就是一个方法的栈帧在虚拟机栈中入栈和出栈的过程
(注意:通常所说的栈,指的就是虚拟机栈,确切地说是虚拟机中局部变量表的一部分)
该区域有两种异常情况:*Error和OutOfMemoryError
堆
虚拟机启动时创建,存在的唯一目的就是存放对象的实例,几乎所有的对象都在该区域分配,是GC的主要工作区
方法区
存储类信息,常量,静态变量等数据。GC在该区的主要目标是针对常量池的回收和对类型的卸载
同时注意该区域有“运行时常量池”,用于存放编译期生成的各种字面变量和符号引用。该池的一个重要特征就是具有动态性,也就是说java不要求常量一定只能在编译期间产生,在运行期间也可以将新的常量放入池中,典型的方法就是String类的intern()方法
举例说明:”HelloWorld”.intern(),返回的仍然是Hello World但是这个方法会检查字符串池中是否有“Hello World”这个字符串。如果存在则返回这个字符串的引用,否则就将该串放入池中(注意:这是在运行期间完成的工作,不是编译期),然后返回这个字符串的引用
同时要注意的是,用new 关键字创建的字符串是不会放入字符串池中的,它有自己的地址空间
可抛出的异常:OutOfMemoryError