ITPub博客

首页 > 数据库 > 数据库开发技术 > 腾讯一面:说下Jvm 内存模型

腾讯一面:说下Jvm 内存模型

原创 数据库开发技术 作者:IT枫斗者 时间:2024-11-13 17:09:02 0 删除 编辑



1. JVM内存模型(JVM Memory Model,JMM)



JVM内存模型(JMM)描述了Java虚拟机(JVM)如何在不同线程之间共享内存,以及如何保证多线程环境下的并发性和可见性。JMM定义了 Java 内存区域的工作原理,特别是如何保证多线程环境中对共享数据的操作是正确和一致的。




主要特点:

主内存(Main Memory):

JVM内存中的所有共享变量(字段)存储在主内存中。

工作内存(Working Memory):

每个线程都有一个工作内存,用于存储线程的局部变量和从主内存读取的共享变量的副本。


关键概念:

可见性:

当一个线程修改了共享变量的值,其他线程应该能够及时看到这个修改。JMM通过锁、volatile等机制来保证可见性。

原子性:

一个操作是不可分割的,即要么完全执行,要么完全不执行。JMM通过锁、synchronized等机制保证原子性。

有序性:

操作的执行顺序应该遵循程序的写入顺序。JMM通过指令重排序的控制机制来确保有序性。


JMM中的两种重要规则:

程序规则:

规定了单线程的执行顺序,即每个线程内指令的执行顺序。

内存规则:

规定了多线程中共享变量的读取和写入的行为,如在主内存中更新的变量,是否需要立即通知其他线程。


2. 堆(Heap)和栈(Stack)



在Java中,堆(Heap)和栈(Stack)是两种常见的内存区域,用于不同目的的数据存储。它们的管理方式、生命周期以及存储的内容有所不同。




堆(Heap):

定义:

堆是JVM运行时数据区的一部分,用于存放对象实例和数组。堆内存由JVM自动管理,JVM负责垃圾回收(GC),清理不再使用的对象。

分配方式:

堆内存是动态分配的,对象在运行时通过new关键字分配到堆中。堆内存的大小通常会通过JVM启动参数进行设置(如 -Xms 和 -Xmx)。

生命周期:

堆中的对象存活时间较长,可能在整个程序运行期间存活,直到没有引用指向它时被垃圾回收(GC)回收。

线程共享:

堆是所有线程共享的内存区域,多线程可以访问堆中的对象。


栈(Stack):

定义:

栈是JVM内存中的一部分,用于存放方法调用的局部变量、方法调用信息(如返回地址)以及方法执行时的控制信息(如程序计数器等)。栈通常是由操作系统进行管理的。

分配方式:

栈内存由JVM为每个线程独立分配,线程在执行方法时,会分配一个栈帧,用于存储该方法的局部变量、参数、返回值等。

生命周期:

栈的生命周期由方法的调用和返回决定。每当一个方法被调用时,JVM为该方法分配一个栈帧,并在方法执行完毕后销毁该栈帧。

线程私有:

栈内存是线程私有的,每个线程都有自己的栈。线程中的局部变量存储在栈内存中,因此线程之间的数据是隔离的。


3. 堆与栈的比较



特性

堆(Heap)

栈(Stack)

存储内容

存储对象实例和数组。

存储局部变量和方法调用的栈帧。

内存管理

由JVM垃圾回收(GC)管理。

由操作系统和JVM自动管理,栈帧随方法的调用和返回而创建和销毁。

分配方式

动态分配内存。

固定大小且LIFO(后进先出)分配内存。

线程间共享

所有线程共享堆内存。

每个线程有自己的栈内存,线程之间互不共享。

访问速度

较慢,内存需要动态分配和回收。

较快,内存是线性分配和释放的。

内存大小

堆的大小通常比栈大,可以通过JVM参数调节。

栈的大小通常较小,受到操作系统限制。

生命周期

对象的生命周期由垃圾回收器管理。

方法调用期间有效,方法结束后栈帧销毁。


4. 堆与栈在Java中的作用



堆:

在Java中,堆用于存储所有的对象实例。对象在堆中创建后,JVM会负责回收这些不再使用的对象(垃圾回收)。当我们通过 new 创建对象时,这些对象会被分配到堆中。堆中的对象是多个线程共享的,所有线程都能访问堆中的对象。

栈:

栈用于存储方法的局部变量、方法调用的状态等信息。每个线程有一个独立的栈,栈中的变量在方法调用时创建,方法返回时销毁。栈中的局部变量只能存活于当前方法的调用期间,栈是线程私有的


5. 堆与栈的应用



堆的应用:

适合存储生命周期较长的对象,如new出来的对象。因为堆内存是动态管理的,所以它适合存储需要共享或长时间存活的对象。比如:一个数据库连接池中的连接对象。

栈的应用:

适合存储临时性的数据,如方法调用过程中的局部变量、参数等。栈的创建和销毁非常快速,因此适合存储短期生命周期的变量。比如:递归调用时每个方法的局部变量和调用信息。



总结

JVM内存模型(JMM)
描述了多线程环境下如何共享内存、保证线程间的通信和一致性。

堆与栈
分别用于存储不同的数据类型和有不同的生命周期,堆用于存储对象实例,栈用于存储方法调用的局部变量和调用信息。它们的管理方式和应用场景也有所不同。


👋 大家好,我是枫哥,一名Java后端开发者!我热衷于探索新技术,并在我的微信公众号上分享关于Java 生态和后端开发的知识。欢迎关注我的公众号,期待与你一起探讨技术的无穷可能!” 目前专注于Java技术分享,覆盖春招、秋招、社招和跳槽相关内容,并提供一对一带徒学习服务。加入 学徒计划,即可享受内推机会和优质资源,签订协议确保就业无忧。此外,我们还推出了‘Java跳槽网’, 为你的求职之路提供全方位支持,助你快速找到理想工作

END



原文作者:IT枫斗者;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论
大家好,我是枫哥,🌟阿里云技术专家、📝资深面试官、🌹Java跳蚤网课堂创始人。技术交流vx:itfdz666,拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。看面试实战视频可以关注b站号:IT枫斗者–Java面试。需要看技术文章,可以关注CSDN:IT枫斗者。

注册时间:2020-05-13

  • 博文量
    183
  • 访问量
    81331