Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >内存空间分析图

内存空间分析图

作者头像
用户7353950
发布于 2022-05-10 12:23:00
发布于 2022-05-10 12:23:00
57600
代码可运行
举报
文章被收录于专栏:IT技术订阅IT技术订阅
运行总次数:0
代码可运行

JAVA 虚拟机内存模型概念

从属于线程的内存区域(栈、计数器)

JVM 的内存划分中,有部分区域是线程私有的,有部分是属于整个 JVM 进程;我们将这部分归为一类。

1. 程序计数器(Program Counter Register),在 JVM 规范中,每个线程都有自己的程序计数器。这是一块比较小的内存空间,存储当前线程正在执行的 Java 方法的 JVM 指令地址,即字节码的行号。如果正在执行 Native 方法,则这个计数器为空。

2. Java 虚拟机栈(Java Virtal Machine Stack),同样也是属于线程私有区域,每个线程在创建的时候都会创建一个虚拟机栈,生命周期与线程一致,线程退出时,线程的虚拟机栈也回收。虚拟机栈内部保持一个个的栈帧,每次方法调用都会进行压栈,JVM 对栈帧的操作只有出栈和压栈两种,方法调用结束时会进行出栈操作。该区域存储着局部变量表,编译时期可知的各种基本类型数据、对象引用、方法出口等信息。

3. 本地方法栈(Native Method Stack)与虚拟机栈类似,本地方法栈是在调用本地方法时使用的栈,每个线程都有一个本地方法栈。

堆(heap)

堆(Heap),几乎所有创建的 Java 对象实例,都是被直接分配到堆上的。堆被所有的

线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生代、老年代的划分。

Java 虚拟机在启动的时候,可以使用“Xmx”之类的参数指定堆区域的大小。

方法区(Method Area)

方法区与堆一样,也是所有的线程所共享,存储被虚拟机加载的元(Meta)数据,包括类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区是一种 java 虚拟机的规范。由于方法区存储的数据和堆中存储的数据一致,实质上也是堆,因此,在不同的 JDK 版本中方法区的实现方式不一样。JDK7 以前,方法区就是堆中的“永久代”。

JDK7 开始去“永久代”,把静态变量、字符串常量池都挪到了堆内存中。JDK8 以后,“永久代”不存在了。存储的类信息、编译后的代码数据等已经移动到MetaSpace(元空间)中,元空间并没有处于堆内存上,而是(直接内存)直接占用的本

地内存(NativeMemory)。

虽然,方法区几经变迁,但是对于我们学习的时候,仍然可以按照最初的规范讲解,先熟悉基本的概念,不必过细的深入底层。再细致的课程,可以参考百战程序员《架构课程:JVM 虚拟机优化》。

运行时常量池(Run-Time Constant Pool)(方法区中)

这是方法区的一部分。常量池主要存放两大类常量:

1. 字面量(Literal),如文本字符串、final 常量值。

2. 符号引用,存放了与编译相关的一些常量,因为 Java 不像 C++那样有连接的过程,

因此字段方法这些符号引用在运行期就需要进行转换,以便得到真正的内存入口地址。

直接内存(Direct Memory)

直接内存并不属于 Java 规范规定的属于 Java 虚拟机运行时数据区的一部分。Java 的NIO 可以使用 Native 方法直接在 java 堆外分配内存,使用 DirectByteBuffer 对象作为这个堆外内存的引用。

程序执行的内存分析过程

为了让初学者顺利的分析内存,更加容易的体会程序执行过程中内存的变化,加深理解。我们将 JAVA 虚拟机内存模型进行简化。在本节课中,Java 虚拟机的内存可以简单的分为三个区域:虚拟机栈 stack、堆 heap、方法区 method area。

虚拟机栈(简称:栈)的特点如下:

1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)

2. JVM 为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

3. 栈属于线程私有,不能实现线程间的共享!

4. 栈的存储特性是“先进后出,后进先出”

5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

堆的特点如下:

1. 堆用于存储创建好的对象和数组(数组也是对象)

2. JVM 只有一个堆,被所有线程共享

3. 堆是一个不连续的内存空间,分配灵活,速度慢!

方法区(又叫静态区,也是堆)特点如下:

1. 方法区是 JAVA 虚拟机规范,可以有不同的实现。

i.JDK7 以前是“永久代”

ii.JDK7 部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中

iii.JDK8 是“元数据空间”和堆结合起来。

2. JVM 只有一个方法区,被所有线程共享!

3. 方法区实际也是堆,只是用于存储类、常量相关的信息!

4. 用来存放程序中永远是不变或唯一的内容。(类信息【Class 对象,反射机制中会

重点讲授】、静态变量、字符串常量等)

我的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MathodTest1 {
    //属性
    int id;
    String name;
    int age;

    //方法
    void study() {

        System.out.println("好好学习,天天向上!");
    }

    //构造方法
    MathodTest1(int id,String name,int age){
        this.id=id;
        this.age=age;
        this.name=name;
    }

    public static void main(String[] args) {
        MathodTest1  t1=new MathodTest1(1001,"谢谢",20);
//        t1.id=1001;
//        t1.name="谢谢";
//        t1.age=20;
        System.out.println(t1.age);
        System.out.println(t1.name);
        System.out.println(t1.id);
        t1.study();
        MathodTest1 t2=new MathodTest1(1002,"欣欣",12);
        System.out.println(t2.age);
        System.out.println(t2.name);
        t2.study();
    }
}

运行内存空间分析图:

从图内存分配图可以得出如下结论:

 同一类的每个对象有不同的成员变量存储空间。

 同一类的每个对象共享该类的方法。

参数传值机制

Java 中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。

· 基本数据类型参数的传值

传递的是值的副本。副本改变不会影响原件。

· 引用类型参数的传值

传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT技术订阅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JVM内存模型基础
我们知道运行一个Java应用程序,我们必须要先安装JDK或者JRE包。这是因为Java应用在编译后会变成字节码,然后通过字节码运行在JVM中,而JVM是JRE的核心组成部分。
架构狂人
2023/08/16
2040
JVM内存模型基础
BAT面试必问题系列:深入详解JVM 内存区域及内存溢出分析
在JVM的管控下,Java程序员不再需要管理内存的分配与释放,这和在C和C++的世界是完全不一样的。所以,在JVM的帮助下,Java程序员很少会关注内存泄露和内存溢出的问题。但是,一旦JVM发生这些情况的时候,如果你不清楚JVM内存的内存管理机制是很难定位与解决问题的。
马士兵的朋友圈
2020/09/09
7540
一问带你彻底了解JVM-Java内存区域详解
Java内存模型在1.8之前和1.8之后略有不同,也就是运行时数据区域,请看如下图:
@派大星
2023/06/28
4680
一问带你彻底了解JVM-Java内存区域详解
Java内存区域详解
Java虚拟机在执行Java程序时,会把它管理的内存划分为若干个不同的数据区域。JDK1.8和之前版本略有不同。
Vincent-yuan
2021/09/01
4700
Java内存区域详解
JVM内存结构探秘及编码实战
在Java的开发过程中,因为有JVM自动内存管理机制,不再需要像在C、C++开发那样手动释放对象的内存空间,不容易出现内存泄漏和内存溢出的问题。但是,正是由于把内存管理的权利交给了JVM,一旦出现内存泄漏和内存溢出方面的问题,如果不了解JVM是如何使用内存的,不了解JVM的内存结构是什么样子的,就很难找到问题的根源,就更难以解决问题。
万猫学社
2022/04/22
3560
JVM内存结构探秘及编码实战
Java 内存区域详解
对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像 C/C++程序开发程序员这样为每一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。
Vincent-yuan
2021/10/26
5010
JVM是如何分配管理内存的?
本文成文参考了《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》和《Java虚拟机规范(Java SE 8版)》,这是两本难得的好书,推荐大家购买实体书籍,后续会考虑在"借书下饭"栏目下开设子专栏,如果需要电子版尝鲜可以关注后私信我。
一头小山猪
2020/04/27
1.2K0
JVM是如何分配管理内存的?
【修订完善版】面试又被 JVM 内存区域虐了?推荐你看看这篇文章!
对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像 C/C++程序开发程序员这样为每一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。
Guide哥
2020/05/08
4100
【修订完善版】面试又被 JVM 内存区域虐了?推荐你看看这篇文章!
JVM: JVM 内存划分
https://www.cnblogs.com/paulwang92115/p/12251476.html
用户5224393
2020/03/10
8250
JVM: JVM 内存划分
JVM内存模型详解「建议收藏」
程序计数器:较小的内存空间, 当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响;
全栈程序员站长
2022/09/05
3K0
JVM内存模型详解「建议收藏」
JVM笔记-运行时内存区域划分
Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分为若干个不同的数据区域。它们各有用途,有些随着虚拟机进程的启动一直存在(堆、方法区),有些则随着用户线程的启动和结束而建立和销毁(程序计数器、虚拟机栈、本地方法栈)。
WriteOnRead
2020/02/13
1K0
JVM笔记-运行时内存区域划分
内存模型以及分区,需要详细到每个区放什么?
Java 内存模型(Java Memory Model, JMM)和 JVM 内存分区是 Java 程序员需要了解的重要概念。下面详细解释每个内存区域的作用和内容。
代码小李
2025/02/02
850
深入浅出JVM(二)之运行时数据区和内存溢出异常
Java虚拟机在运行Java程序时,把所管理的内存分为多个区域, 这些区域就是运行时数据区
菜菜的后端私房菜
2024/09/25
2560
8张图 带你理解Java内存区域
Java内存区域是指 JVM运行时将数据分区域存储 ,简单的说就是不同的数据放在不同的地方。通常又叫 运行时数据区域。
HaC
2020/11/16
3.3K0
Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
今天介绍一下JVM内部的一些区域,以及具体的区域在运行过程中会发生哪些异内存常! 其实也就对应了内存管理的第一篇中 JVM的第三个阶段,程序运行内存溢出。
凯哥Java
2022/12/15
1.7K0
Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
【JVM进阶之路】二:Java内存区域
Java 虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。
三分恶
2021/04/01
3570
【JVM进阶之路】二:Java内存区域
深入理解 Java 虚拟机(第一弹) - Java 内存区域透彻分析
这篇文章主要介绍Java内存区域,也是作为Java虚拟机的一些最基本的知识,理解了这些知识之后,才能更好的进行Jvm调优或者更加深入的学习,本来这些知识是晦涩难懂的,所以希望能够讲解的透彻且形象。
好好学java
2019/12/19
3800
JVM内存区域
JVM虚拟机,也就是虚拟的计算机,它有自己虚拟的CPU、虚拟的内存等等,当然还有大名鼎鼎的垃圾回收器。第一篇我们来讲解一下JVM的虚拟内存。
用户4439777
2020/08/01
9680
快速串讲——JVM内存的区域划分
目的 快速定位JVM内存泄漏或者溢出等问题。 面试基础题,加分项。 程序计数器(Program Counter Register) 记录当前线程所执行的字节码的行号。 依赖其实现分支、循环、跳转、异常处理、线程恢复。 Natvie 方法时,其的值就为空。 Java 虚拟机规范中唯一没有规定内存溢出的区域。 “线程私有”的内存区域。 虚拟机栈(Virtual Machine Stacks) 其生命周期与线程相同。 存储局部变量表、操作数栈、动态链接、方法出口等信息。 方法被执行的时候创建一个栈帧并入
万猫学社
2022/04/22
3730
快速串讲——JVM内存的区域划分
JVM系列分析- 内存模型
JVM的内存模型是java语言绕不开的一个话题。要进行java的性能调优,首先就要了解其内存模型。在诸多的面试笔试中,这也是很多面试官会考察的内容。
JathonKatu
2020/10/27
3490
JVM系列分析- 内存模型
相关推荐
JVM内存模型基础
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验