码迷,mamicode.com
首页 > 编程语言 > 详细

JVM -- java内存区域

时间:2019-11-11 14:17:21      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:time   忽略   执行时间   共享   没有   OLE   基本类型   基本   加载   

一、运行时数据区域

  java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。

技术图片

 二、区域介绍

  1. 程序计数器

    程序计数器(Program Counter Register)是一块较小的内存空间,是当前线程所执行的字节码的行号指示器。(在VM的概念模型里,字节码解释器的工作是。通过改变计数器的值,选取下一条需要执行的字节码指令,分支、循环、跳跃、异常处理、线程恢复等基础功能,这些都学要计数器来完成)。

    JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有独立的程序计数器,且各线程的计数器互不影响,独立储存。所以像这种内存区域为“线程私用”的内存。

    如果线程正在执行的是一个Java方法, 这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是Native方法, 这个计数器值则为空(Undefined).  此内存区域是唯一 一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域.。

  2. java虚拟机栈

    同样,java虚拟机栈是线程私有,它的生命周期与线程相同。虚拟机栈描述的是java方法执行的内存模型;每个方法在执行的同时都会创建一个栈帧(Stack Frame)[方法运行时的基础数据结构]。

    用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

    局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 returnAddress 类型(指向了一条字节码指令的地址)。

    异常:StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。 OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。

  3. 本地方法栈

    本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是非常相似的,主要区别是虚拟机栈为虚拟机执行java方法(字节码)服务;而本地方法栈则为虚拟机使用到的Native方法服务。

    异常:StackOverflowError 和 OutOfMemoryError 异常。

  4. 堆

    对于绝大多数应用来说,java堆(java heap)是jvm所管理的最大的一块内存。java堆也是线程共享的区域,在虚拟机启动时创建,它的唯一目的是存放对象实例和数组

    java堆是垃圾收集器管理的主要区域,因此也程“GC堆”。

    可以位于物理上不连续的空间,但是逻辑上要连续。实现时,既可实现固定大小,也可扩展。

  5. 方法区

    方法区(Method Area)和java堆一样,是各个线程共享的内存区域。

    它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

现在用一张图来介绍每个区域存储的内容。

技术图片

 

   6.运行时常量池

    运行时常量池(Runtime Constant Pool) 是方法区的一部分. Class文件中除了有类的版本, 字段,方法, 接口等描述信息外, 还有一项信息是常量池(Constant Pool Table), 用于存放编译期生成的各种字面量和符号引用这部分内容将在类加载后存放到方法区的运行时常量池中. 

    运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性, Java语言并不要求常量一定只能在编译期产生, 也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池, 运行期间也可能将新的常量放入池中, 这种特性被开发人员利用的比较多的便是String类的intern() 方法.

  7.直接内存

     直接内存(Direct Memory) 并不是虚拟机运行时数据区的一部分, 也不是Java虚拟机规范中定义的内存区域, 但是这部分内存也被频繁地使用, 而且也可能导致OutOfMemoryError异常出现.

     显然, 本机直接内存的分配不会受到Java堆大小的限制, 但是, 既然是内存, 则肯定还是会受到本机总内存的大小及处理器寻址空间的限制. 

     服务器管理员配置虚拟机参数时, 一般会根据实际内存-Xmx等参数信息, 但经常会忽略到直接内存, 使得各个内存区域的总和大于物理内存限制(包括物理上的和操作系统级的限制), 从而导致动态扩展时出现OutOfMemoryError异常. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

JVM -- java内存区域

标签:time   忽略   执行时间   共享   没有   OLE   基本类型   基本   加载   

原文地址:https://www.cnblogs.com/FondWang/p/11834538.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!