JVM 运行时数据区详解

简介: 一、运行时数据区:   Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同数据区域。     1.有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,所有的线程共享这些数据区。

一、运行时数据区:

  Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同数据区域。

    1.有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,所有的线程共享这些数据区。

    2.第二种则是与线程一一对应,随线程的开始和结束而创建和销毁,线程之间相互隔离。

java虚拟机所管理的内存将会包括以下几个运行时数据区域

    

二、数据区详解

1.程序计数器(Program Counter Register)

  • 也叫PC寄存器是一块较小的内存空间,它的作用是存储当前线程所执行的字节码的信号指示器。
  • 每一条JVM线程都有自己的PC寄存器。
  • 在任意时刻,一条JVM线程只会执行一个方法的代码。该方法称为该线程的当前方法(Current Method)。
  • 如果该方法是java方法,那PC寄存器保存JVM正在执行的字节码指令的地址。
  • 如果该方法是native,那PC寄存器的值是undefined。
  • 此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

2.Java虚拟机栈(Java Virtual Machine Stack)

  • 每一个JVM线程都有自己的java虚拟机栈,这个栈与线程同时创建,它的生命周期与线程相同。
  • 用于存储局部变量、操作栈、动态链接、方法出口
  • 虚拟机栈描述的是Java方法执行的内存模型:
    • 每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
    • 每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
    • 局部变量表存放了编译器克制的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(Object reference)和字节码指令地址(returnAddress类型)。
  • JVM stack 可以被实现成固定大小,也可以根据计算动态扩展。
    • 如果采用固定大小的JVM stack设计,那么每条线程的JVM Stack容量应该在线程创建时独立地选定。
    • JVM实现应该提供调节JVM Stack初始容量的手段。
    • 如果采用动态扩展和收缩的JVM Stack方式,应该提供调节最大、最小容量的手段。
  • 对于32位的jvm,默认大小为256kb, 而64位的jvm, 默认大小为512kb,可以通过-Xss设置虚拟机栈的最大值。不过如果设置过大,会影响到可创建的线程数量。
  • JVM Stack 异常情况:
    • StackOverflowError:当线程请求分配的栈容量超过JVM允许的最大容量时抛出.
    • OutOfMemoryError:如果JVM Stack可以动态扩展,但是在尝试扩展时无法申请到足够的内存去完成扩展,或者在建立新的线程时没有足够的内存去创建对应的虚拟机栈时抛出。

3.本地方法栈(Native Method Stack)

  • Java虚拟机可能会使用到传统的栈来支持native方法(使用Java语言以外的其它语言编写的方法)的执行,这个栈就是本地方法栈.
    • 如果JVM不支持native方法,也不依赖与传统方法栈的话,可以无需支持本地方法栈。
    • 如果支持本地方法栈,则这个栈一般会在线程创建的时候按线程分配。
  • 异常情况:
    • StackOverflowError:如果线程请求分配的栈容量超过本地方法栈允许的最大容量时抛出.
    • OutOfMemoryError:如果本地方法栈可以动态扩展,并且扩展的动作已经尝试过,但是目前无法申请到足够的内存去完成扩展,或者在建立新的线程时没有足够的内存去创建对应的本地方法栈,那Java虚拟机将会抛出一个OutOfMemoryError异常。

注:以上三个数据区属于各个线程单享的,每个线程创建时都会创建此三个数据区。各个线程之间相互隔离,互不影响。

4.方法区(Method Area)

  • 方法区是可供各条线程共享的运行时内存区域。存储了每一个类的结构信息,例如:运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法。
  • 方法区在虚拟机启动的时候创建。
  • 方法区的容量可以是固定大小的,也可以随着程序执行的需求动态扩展,并在不需要过多空间时自动收缩。
  • 方法区在实际内存空间中可以是不连续的。
  • Java虚拟机实现应当提供给程序员或者最终用户调节方法区初始容量的手段,对于可以动态扩展和收缩方法区来说,则应当提供调节其最大、最小容量的手段。
  • Java 方法区异常:
    • OutOfMemoryError: 如果方法区的内存空间不能满足内存分配请求,那Java虚拟机将抛出一个OutOfMemoryError异常。

运行时常量池(Runtime Constant Pool

  • 运行时常量池是每一个类或接口的常量池(Constant_Pool)的运行时表现形式,它包括了若干种常量:编译器可知的数值字面量到必须运行期解析后才能获得的方法或字段的引用。
  • 运行时常量池是方法区的一部分。每一个运行时常量池都分配在JVM的方法区中,在类和接口被加载到JVM后,对应的运行时常量池就被创建。
  • 在创建类和接口的运行时常量池时,可能会遇到的异常:
    • OutOfMemoryError:创建类和接口时,若构造运行时常量池所需的内存空间超过了方法区所能提供的最大内存空间后时抛出.

5.Java堆(Heap)

  • 在JVM中,堆是可供各条线程共享的运行时内存区域,也是供所有类实例和数据对象分配内存的区域。
  • Java堆是Java虚拟机所管理的内存中最大的一块。
  • 通过-Xms和-Xmx来控制初始堆大小和最大堆大小
  • Java堆载虚拟机启动的时候就被创建,堆中储存了各种对象,这些对象被自动管理内存系统(Automatic Storage Management System,也即是常说的“Garbage Collector(垃圾回收器)”)所管理。这些对象无需、也无法显示地被销毁。
  • Java堆的容量可以是固定大小,也可以随着需求动态扩展,并在不需要过多空间时自动收缩。
  • Java堆所使用的内存不需要保证是物理连续的,只要逻辑上是连续的即可。
  • JVM实现应当提供给程序员调节Java 堆初始容量的手段,对于可动态扩展和收缩的堆来说,则应当提供调节其最大和最小容量的手段。
  • Java 堆异常:
    • OutOfMemoryError:如果实际所需的堆超过了自动内存管理系统能提供的最大容量时抛出。

参考原文:http://chenzhou123520.iteye.com/blog/1585224

     http://www.open-open.com/lib/view/open1383745340321.html

相关文章
|
12天前
|
Java
JVM运行时数据区
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一
17 2
|
18天前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
19 3
|
2月前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
69 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
2月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
36 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
2月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
60 3
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
32 3
|
4月前
|
消息中间件 设计模式 安全
多线程魔法:揭秘一个JVM中如何同时运行多个消费者
【8月更文挑战第22天】在Java虚拟机(JVM)中探索多消费者模式,此模式解耦生产与消费过程,提升系统性能。通过`ExecutorService`和`BlockingQueue`构建含2个生产者及4个消费者的系统,实现实时消息处理。多消费者模式虽增强处理能力,但也引入线程安全与资源竞争等挑战,需谨慎设计以确保高效稳定运行。
98 2
|
4月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
206 0
|
18天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
158 1
|
2月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
40 4