java内存管理

本文为<<深入理解java虚拟机>>一书的学习笔记

我们知道,在java管理的内存区域中,共分为5个部分。如下图:


java内存管理_第1张图片

虚拟机栈

虚拟机栈是线程私有的,它描述的是java方法执行的内存模型:每一个方法在执行期间都会创建一个栈帧用来存储局部变量表,操作数栈,动态链接,方法出口等信息。

我们重点说说局部变量表。局部变量表里面存放的是各种基本类型(int,char等等)和引用类型。当然引用类型并不是对象本身,而是指向数据存储位置的一个指针。

每一个线程启动的时候,jvm都会为它创建一个对应的虚拟机栈,而每一个方法都会有一个栈帧。我们看下面的例子

public void m1(int args){

      int b=10;

      Person p=new Person();

      Object o=new Object();

       m2();

        ....

}

public void m2(){

    .....

}

当程序执行到m2内部的时候

虚拟机栈大致内容如下

java内存管理_第2张图片

当然当m2方法执行完毕后,它所代表的栈帧就会消失,此时的栈顶就是m1所代表的按个栈帧。

同时b和args里面直接存放具体数值,而p与o为引用变量,里面存放的是堆的一个地址。

在虚拟机栈里面,有两种异常状况。
1 如果请求的栈深度大于虚拟机所允许的深度,将会跑出StackOverflowError。
2 现在的虚拟机栈一般都可以动态扩展,如果扩展时申请不到足够的内存就会抛出OutOfMemoryError异常。

本地方法栈

它与虚拟机的区别在于,虚拟机栈为java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用的Native方法服务。
当然本地方法栈也会抛出StackOverflowError与OutOfMemoryError。

 java堆

java堆是java虚拟机管理的最大一块内存。且被所有线程共享。这块区域在虚拟机启动时就会创建。它存在的唯一目的就是存放对象。
另一方面java堆也是垃圾收集管理的主要区域。关于垃圾收集与管理,我们后面再说。

方法区

方法区也是各个线程所共享的。它存储已被虚拟机加载的类信息,常亮,静态变量,即时编译器编译后的代码等等。

 运行时常量池

 运行时常量池是方法区的一部分。Class文件里除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池,用于存放编译期间上次的各种字面量和符号引用。

程序计数器

可以看做是当前线程所执行的字节码的行号指示器。



参考资料:

深入理解java虚拟机 第二章

你可能感兴趣的:(虚拟机,栈,堆,内存管理,方法区)