一、运行时的数据区域

Java 在执行的过程中,会把它所管理的内存瓜分成不同的区域。

image_thumb1

程序计数器

        当前线程执行字节码的行号指示器。所占内存小,是唯一一个java虚拟机中不会出现OutOfMemoryError 情况的区域。

  • JAVA虚拟机栈

          每个方法在执行的时候同时也会创建一个栈帧。用于操作局部变量表、操作栈、动态链接、方法出口等信息。

           局部变量表:基本的数据类型(boolean、byte 、char 等),对象的引用。

          

           两种情况会出现异常状况:

           线程请求的栈深度 大于 虚拟机所允许的深度,将抛出StackOverflowError 异常;        

           如果线程请求可以动态扩展,当扩展无法申请到足够的内存时将抛出  OutOfMemoryError  异 常。

    image_thumb[1]

    一个线程有独立的程序计数器和虚拟机栈

  • 本地方法栈

           服务的是本地的native 方法。有些虚拟机(eg: sun HotSpot 虚拟机)直接把java虚拟机栈和本地方法栈合二为一。本地方法栈也会抛出OutOfMemoryError 和 StackOverflowError 异常。

    Java 堆

           java堆是管理内存中最大的一块。java堆是被所有线程共享。它的目的就是存放对象的实例。所以这也是垃圾收集经常光顾的地方。

           如果在堆中没有足够的内存分配实例,并且也无法扩展时。将会抛出OutOfMemoryError  异常。

     方法区

          方法区与java堆一样,也是各个线程共享的区域。它主要存储:虚拟机加载的类信息、常量、静态常量等等的数据。

    经常称为“永久代”。如果方法区无法分配足够内存需求时,也会抛出OutOfMemoryError  异常。

    image_thumb[2]

    运行时常量池是方法区的一部分、用于存储编译期间生成的各种字面量和符号引用。

    image_thumb[3]

    各个线程都共享 java堆和方法区。

原文地址:https://www.cnblogs.com/pan2011/p/3577108.html