当前位置: 首页 > news >正文

谈谈JVM的内存区域

什么是jvm?

JVM(Java虚拟机)是运行所有Java应用程序的假想计算机。它是Java运行时环境的一部分,为Java应用程序提供了跨平台执行的能力。JVM主要负责两件事情:一是加载编译后的Java字节码到其运行时环境中,二是执行这些字节码。JVM在执行字节码时,会进行解释执行或JIT(即时编译)执行,以提高程序运行效率。下面是JVM的几个关键组成部分和它们的功能:

  1. 类加载器(Class Loader):JVM的类加载器负责加载Java应用程序的类。这一过程分为加载、链接(验证、准备和解析)、和初始化三个主要阶段。

  2. 运行时数据区(Runtime Data Areas):当JVM启动时,它会创建一块运行时数据区,这块区域被用来存储运行Java应用时产生的各种数据。这包括:

    • 方法区(Method Area):存储每个类的结构信息,如运行时常量池、字段和方法数据、构造函数和普通方法的代码等。
    • 堆(Heap):所有的Java对象和与之相关的数组都在堆中分配。堆是JVM中唯一的一块所有线程共享的内存区域。
    • 栈(Stacks):Java虚拟机栈是线程私有的,它的生命周期与线程相同。每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
    • 程序计数器(Program Counter Register):每个线程都有一个程序计数器,是当前线程所执行的字节码的行号指示器。
    • 本地方法栈(Native Method Stacks):与操作系统相关,为支持native方法执行。
  3. 执行引擎(Execution Engine):执行引擎负责执行类文件中的字节码。它可以通过解释字节码或者即时编译(JIT编译器)将字节码转换为本地机器码执行,提高性能。

  4. 本地库接口(Native Interface):为Java提供与操作系统交互的接口,使得Java能够调用本地库(C/C++等编写)方法实现更多功能。

  5. 垃圾收集器(Garbage Collector):自动管理Java堆内存的系统,它可以自动回收不再使用的对象所占用的内存空间,防止内存泄漏。

JVM的内存区域?

JVM(Java虚拟机)的内存区域主要分为以下几个部分,每个部分都有其特定的作用和管理的数据类型。这些区域共同协作,确保Java应用程序的高效运行。下面是JVM内存区域的详细介绍:

1. 方法区(Method Area)

方法区是所有线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。在Java 8之前,这个区域通常被称为永久代(PermGen space),从Java 8开始,永久代被元空间(Metaspace)所取代。

2. 堆(Heap)

堆是JVM管理的最大的一块内存区域,也是被所有线程共享的。它用于存放对象实例和数组。堆是垃圾收集器管理的主要区域,因此也被称为GC堆(Garbage Collected Heap)。根据对象存活周期的不同,堆可以细分为年轻代(Young Generation)、老年代(Old Generation)和(在某些情况下的)永久代或元空间。

  • 年轻代主要包括一个或多个Eden区以及两个Survivor区(通常称为from和to)。大部分新生成的对象首先在Eden区分配。年轻代的特点是区域相对较小,对象存活率低,垃圾收集频繁。
  • 老年代用于存放长时间存活的对象。相比年轻代,它的大小和回收频率都有所不同,对象存活率高,垃圾收集不那么频繁。
  • 元空间(Metaspace,Java 8及之后的版本)或永久代(PermGen,Java 8之前的版本)主要存放类的元数据,Java 8通过引入元空间来避免永久代的内存溢出问题。
  1. 年轻代和老年代的比例

    • 在HotSpot JVM中,默认的年轻代与老年代的比例约为1:2,即如果堆大小被设置为默认值,则年轻代占整个堆的1/3,老年代占2/3。
    • 这个比例可以通过-XX:NewRatio参数进行调整。例如,-XX:NewRatio=3意味着老年代将占据堆的3/4,年轻代占1/4。
  2. 年轻代内部的分配(Eden与Survivor区)

    • 年轻代内部,默认的Eden与Survivor区的比例是8:1:1,即Eden区占年轻代的80%,每个Survivor区占10%。
    • 这个比例可以通过-XX:SurvivorRatio参数进行调整。例如,-XX:SurvivorRatio=8将Eden与每个Survivor区的比例设置为8:1。

大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 S0 或者 S1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

3. Java栈(Java Stack)

Java栈是线程私有的,它的生命周期与线程相同。每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接信息和方法出口信息等。一旦方法执行结束,其对应的栈帧就会被销毁。

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

本地方法栈与Java栈类似,不过它是为虚拟机使用到的Native方法服务的。在Java中调用非Java代码(如C或C++编写的代码)时使用。

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

程序计数器是线程私有的内存区域,可以看作是当前线程所执行的字节码的行号指示器。每个线程都有一个独立的程序计数器,若线程正在执行一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,则计数器值为空(Undefined)。

 

相关文章:

  • 二分图的判断与匹配
  • 初识MySQL(中篇)
  • 增加网站搜索引擎排名的6个准则
  • 芯片工程系列(6)Chiplet封装
  • 如何快速入门TensorFlow
  • 数据库面试题之Mysql
  • 腾讯云2023: 容器与函数计算实践精选,引领Serverless与Docker容器新趋势
  • LLaMA-Factory微调(sft)ChatGLM3-6B保姆教程
  • websocket多级nginx代理
  • 八大排序(尚未完善)
  • 6-95 希尔排序(Java语言描述)
  • 设计模式——抽象工厂模式02
  • 1236. 递增三元组:做题笔记
  • acwing算法提高之图论--floyd算法及其扩展应用
  • 江协STM32:定时器定时中断和定时器定时闹钟
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Apache Spark Streaming 使用实例
  • Codepen 每日精选(2018-3-25)
  • ES10 特性的完整指南
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Js基础知识(一) - 变量
  • Making An Indicator With Pure CSS
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • python 装饰器(一)
  • Python学习之路13-记分
  • Ruby 2.x 源代码分析:扩展 概述
  • webpack4 一点通
  • Web标准制定过程
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用Swoole加速Laravel(正式环境中)
  • 我建了一个叫Hello World的项目
  • 怎么将电脑中的声音录制成WAV格式
  • Java数据解析之JSON
  • #define用法
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (笔试题)合法字符串
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (接口自动化)Python3操作MySQL数据库
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)jdk与jre的区别
  • (转)shell调试方法
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .gitignore文件_Git:.gitignore
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .Net 高效开发之不可错过的实用工具
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET4.0并行计算技术基础(1)
  • .NetCore 如何动态路由
  • .sdf和.msp文件读取