java程序员把内存控制的权力交给了虚拟机,一旦出现内存泄露和溢出的问题,如果不了解虚拟机是怎样使用内存的,排错会非常难。
java虚拟机在执行java程序过程中会把他管理的内存区域分成若干个不同的数据区域,这些区域
都有各自的用途,以及创建销毁的时间,有的依赖虚拟机进程启动而存在。有的区域则是依赖用户线
程的启动和结束而建立或销毁
程序计数器(program center register)是一块较小的内存空间
在虚拟机的概念模型里,字节码解释器工作时就是根据程序计数器来选取下一条需要执行的字
节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能 都需要依赖计数器来完成多线程是
通过线程轮流切换并 分配处理器执行时间的方式来完成的,任何一个时刻,一个处理器都只会执行
一条线程中的指令为了线程切换后能恢复到正确的执行位置,每个线程都需要一个独立的计数器
。各条线程之间互不影响独立存储。 称这类内存区域为线程私有内存.
java虚拟机栈 也是线程私有 他的生命周期和栈相同
虚拟机栈描述的是java方法执行的内存模型: 在每个方法执行的同时都会创建一个栈帧(stack
frame)用于存储局部变量表(各种基本数据类型和对象的引用)、操作数栈、动态链接、方法出口等息
每一个方法从执行到调用完成的过程 就对应着在虚拟机栈中一次出栈入栈的过程
局部变量表存放了编译期可知的各种基本数据类型和对象的引用 和returnAddress类型(指向了一条字节码的地址.
其中64位长度的long和double数据类型会占用两个局部变量空间,其余的类型只占用一个
局部变量表所需的内存空间是在编译期就确定的 进入方法之后不会在改变
太深会抛出 StackOverflowError 扩展时无法申请到足够的内存 OutOfMemoryError
本地方法栈和虚拟机栈非常类似,区别是本地方法栈则是虚拟机使用到的Native方法服务
JAVA堆 java heap 是java虚拟机所管理的内存中最大的一块java堆是被所有线程共享的一块内存区
域 在虚拟机启动时创建此区域的唯一目的就是存放对象实例 几乎所有的对象实例都在这里分配内
存(数组也是的)如果在堆中没有内存完成实例分配,并且堆也无法在扩展时,将会抛出
OutOfMemoryError方法区也是各个线程共享的区域 他用于存储已被虚拟机加载的类信息,常量,静
态常量、即时编译器编译后的代码等数据运行时常量池是方法区的一部分 Class文件中除了有 类的
版本 字段 方法 接口等描述信息外 还有一项信息是常量池 用于编译期生成的各种字面量和符号引
用 这部分内容将在类加载后进入方法区的常量池中存放除了编译期 运行期也可以把新生的常量放
入池中 用的较多的是String类的intern()方法服务器管理员在分配内存时 经常使用 设置-Xmx 等参数
信息 也要注意直接内存