jvm——模型

1、 总体结构

    JVM内存模型,又称为JVM运行时数据区,总体结构如下图:
在这里插入图片描述

1.1 共享数据区

    一个jvm进程中一般会存在多个线程,而共享数据区就是指所有线程都可以访问到的内存空间,图中灰色部分几位共享数据区。

1.1.1 堆

    我们上学的时候老师说过java内存中分为堆和栈,而老师口中的堆,其实就是这里的堆,java虚拟机规范上描述中说,所有的对象实例包括数组的内存都要在堆上分配(随着jit编译器,逃逸分析技术的发展,现在不是那么绝对了),所以很好理解对于大多数应用来说堆是最大的一块内存区域了,其生命周期是和虚拟机共生共灭的,但是堆上的对象则是会被回收的,堆也是GC回收的主要战场。根据java虚拟机规范定义,堆是可以在不连续的内存空间上的,所以只要逻辑允许,堆是可扩展的。

1.1.2 方法区

    方法区可以理解为代码逻辑层,或者说叫堆的逻辑层,比如编译后的正在执行的代码,静态变量,加载的那些类的基本信息,以及常量池都在方法区中。方法区和堆一样也需要参与到垃圾回收,起主要回收目标是常量池和对类进行卸载。异常方面和堆一样,当无法满足内存分配需求时就会报内存溢出。

1.2 线程独占内存区

    线程独占也很好理解,指这部分内存归属于当前线程,其他线程是无法访问的,所以我们一般讨论线程安全的时候,都是只共享数据区中数据存在线程安全问题。线程独占内存区是不存在线程安全问题的,他们都是线程安全的,其他线程根本无法访问。

1.2.1 程序计数器

    图中程序计数器占了很大一块地方,实际上在jvm内存中,程序计数器是一块很小的内存。程序计数器是用来记录当前线程,目前执行到了哪一行指令的,原因是多线程之间是存在上下文切换的(写多线程的时候讲过),而程序计数器的存在就是为了防止当上下文重新切换回来时还找得到当前线程执行到了哪一步了。当线程执行的是java方法时,计数器记录的值即为正在执行的jvm中字节码指令的地址,如果线程执行的是native方法(非java方法时),此时计数器的值为空(Undefined)。程序计数器是虚拟机中唯一一块不会OOM的区域。

1.2.2 虚拟机栈

    在java方法执行过程中所产生的的对象就存储在这个区域中。当一个方法执行时就会创建一个栈帧,用于存放局部变量表,操作数栈,动态链接,方法出口等信息,方法执行的过程就对应着虚拟机栈入栈出栈的过程。虚拟机栈中的局部变量表应该是我们最容易理解也最关键的部分,我们在方法中的创建的每一个变量都在这里面。

1.2.2 本地方法栈

    本地方法栈和虚拟机栈的功能是一样的,唯一区别是虚拟机栈是为java方法服务,而本地方法栈是为native方法服务。由于java虚拟机规范中对本地方法栈的限制很少,所以各家厂商的实现不尽相同,甚至有把本地方法栈融入到虚拟机栈中的。异常方面和堆一样,当无法满足内存分配需求时就会报内存溢出。

    jvm内存模型是我们经常在面试中遇到的问题,但是从实用角度来说,学习jvm内存模型到底有什么用呢?在一个低并发,低内存消耗的系统中这些自然都不用考虑,但是反之则需要认真考虑内存是否够用的问题,是哪部分内存溢出了,溢出原因是什么,是选择添加集群还是可以尝试优化代码?这些判断都需要建立在我们对jvm内存模型掌握的基础之上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVMJava虚拟机)的分代模型是一种内存管理策略,将堆内存划分为不同的代(Generation),包括年轻代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,JDK8之后被元空间(Metaspace)取代)。下面是JVM分代模型的执行流程: 1. 初始阶段:当Java应用程序启动时,JVM会为其分配一块初始的堆内存空间。此时,年轻代和老年代都是空的。 2. 对象创建:当Java程序创建对象时,对象会被分配在年轻代的Eden区域。如果Eden区域没有足够的空间来存放新创建的对象,就会触发一次垃圾回收(Minor GC)。 3. Minor GC:在Minor GC中,垃圾回收器会扫描年轻代的Eden区域和Survivor区域,将不再被引用的对象进行回收。存活的对象会被移动到Survivor区域中的一个空闲区域。 4. 对象晋升:当一个对象经过多次Minor GC后仍然存活,它会被晋升到老年代。晋升条件可以根据不同的垃圾回收器而有所不同。 5. Major GC:当老年代空间不足时,会触发一次Major GC(也称为Full GC)。在Major GC中,垃圾回收器会扫描整个堆内存,对不再被引用的对象进行回收。 6. 永久代/元空间:永久代(JDK8之前)或元空间(JDK8及以后)用于存放类的元数据和常量池等信息。当类的元数据不再被使用时,会触发一次永久代/元空间的垃圾回收。 7. 内存分配担保:在进行垃圾回收时,如果老年代的空间不足以存放新创建的对象,JVM会进行一次内存分配担保。即使触发了垃圾回收,也能保证新创建的对象能够顺利分配到老年代。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值