程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(2)

JVM 内存区域

发布于2021-06-12 14:03     阅读(699)     评论(0)     点赞(24)     收藏(3)


内存区(运行时数据区):

Java 虚拟机在执行Java程序的过程中会把它所管理的内存划分为 5 个区域,如图

image

  • 线程共享内存区:方法区,堆
  • 线程私有内存区:虚拟机栈,本地方法栈,程序计数器
    image

方法区(MethodArea):

用于储存结构信息的地方,包括常量池、静态常量、构造函数等。(运行时常量池)

java堆(Heap):

对象实例(几乎所有),数组。这块是 GC 的主要区域。

java栈(Stack)(虚拟机栈):

java 栈总是和线程关联在一起,每当创一个线程时,JVM 就会为这个线程创建一个对应的 java 栈,在这个栈中,又会包含多个栈帧,每运行一个方法就建一个栈帧,用于存储局部变量表操作数栈动态连接(多态)、返回地址等。每一个方法从调用直至执行完成的过程,就对应一栈帧在 java 栈中入栈到出栈的过程。(为什么 JVM 要使用栈?非常符合Java中方法间的调用)

栈溢出

无限递归会导致栈溢出,一般的方法调用很难出现。

程序计数器(PCRegister)

指向当前线程正在执行的字节码指令的地址(用于保存当前线程执行的内存地址)。由于 JVM 程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立计数器,记录之前中断的地方,可见程序计数器也是线程私有的。

本地方法栈(Native MethodStack):

保存的是 native 方法的信息,只不过是为 JVM 使用到 native 方法服务的。虚拟机规范无强制规定,各版本虚拟机自由实现。

开线程影响哪块内存?

每当线程被创建的时候,JVM 就需要为其在内存中分配虚拟机和本地方法栈记录调用方法的内容,分配程序计数器记录指令执行的位置,这样的内存消耗就是创建线程的内存代价。

虚拟机中的对象

image

对象的分配:虚拟机遇到一条new指令时

1. 检查类加载

先执行相应的类加载过程。

2. 分配内存

image

  • 指针碰撞:如果java堆中内存是绝对规整的,用过内存与空闲内存各放一边,中间放着一个指针作为分界点的指示器,那指针向空间那边挪动一段与对象大小相等的距离为分配内存,这种分配方式称为“指针碰撞”。
  • 空闲列表:如果java堆中内存不是规整的,使用的内存和空闲的内存相互交错,虚拟机就必须维护一个列表,记录哪些内存块是可以用的,在分配内存的时候找到一块空间划分给对象实例,并更新列表记录,这种方式称为“空闲列表”。

分配内存涉及到并发安全问题:
多个线程同时对一块内存进行分配。这里解决有2种方案

CAS 机制:虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性;

分配缓冲:把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在 Java 堆中预先分配一小块私有内存,也就是本地线程分配缓冲。

CAS (Compare and swap)比较和交换

CAS 操作需要输入两个数值,一个酒店旧值 A(期望操作前的值)和一个新值B,在操作期间会先比较旧值有没有变化,如果没有变化,才换成新值,否则不进行交换。

image

3. 内存空间初始化

(注意不是构造方法)内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(如int值为0,boolean值为false等)。这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型锁对应的零值。

4. 设置

虚拟机对对象进行必要的设置,例如这个对象是哪个实例、如何才能找到类的元数据信息、对象的哈希吗、对象的GC 分代年龄等信息。这些信息存放在对象的对象头之中。

5. 对象初始化

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从 Java 程序的视角看,对象创建才刚刚开始,所有的字段都还为零值。所以,一般来说,执行 new 指令之后会接着把对象按照程序员的医院意愿进行初始化,这样一个真正可用的对象才算完全产生处理。

对象的内存布局

在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头、实例数据、对齐填充。

  • 对象头:保存2部分信息,第一部分用于存储对象自身的运行时数据,如哈希吗(HashCode)、GC 分代年龄、锁状态标注、线程持有的锁等。

原文链接:https://blog.csdn.net/qq_36865892/article/details/117786031



所属网站分类: 技术文章 > 博客

作者:想要飞翔的天使

链接:http://www.javaheidong.com/blog/article/222159/028bbafa4eaa59e78a1f/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

24 0
收藏该文
已收藏

评论内容:(最多支持255个字符)