JVM内存模型理解

深入理解Java的JVM内存模型 JVM内存模型定义了Java程序在执行时如何分配和管理内存。JMM的主要目的是屏蔽不同硬件、操作系统的内存访问差异,确保Java程序在各种环境下都能获得一致的执行效果。在JVM中,内存分为多个区域,每个区域负责不同类型的数据存储。这些区域大致包括方法区、堆、栈、本地方法栈和程序计数器。 阅读详情

原文地址:https://www.cnblogs.com/junzi2099/p/8418009.html

原文地址:https://www.cnblogs.com/zoudongdong/p/7429220.html

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。

JVM内存模型可以分为两个部分,如下图所示,堆和方法区是所有线程共有的,而虚拟机栈,本地方法栈和程序计数器则是线程私有的。下面我们就来分析一下这些不同区域的作用。

jvm-memory-model

堆内存

堆内存是所有线程共有的,可以分为两个部分:年轻代和老年代。下图中的Perm代表的是永久代,但是注意永久代并不属于堆内存中的一部分,同时jdk1.8之后永久代也将被移除。

jvm-heap-memoryjvm-heap-memory

GC(垃圾回收器)对年轻代中的对象进行回收被称为Minor GC,用通俗一点的话说年轻代就是用来存放年轻的对象,年轻对象是什么意思呢?年轻对象可以简单的理解为没有经历过多次垃圾回收的对象,如果一个对象经历过了一定次数的Minor GC,JVM一般就会将这个对象放入到年老代,而JVM对年老代的对象的回收则称为Major GC。

如上图所示,年轻代中还可以细分为三个部分,我们需要重点关注这几点:

  1. 大部分对象刚创建的时候,JVM会将其分布到Eden区域。
  2. 当Eden区域中的对象达到一定的数目的时候,就会进行Minor GC,经历这次垃圾回收后所有存活的对象都会进入两个Suvivor Place中的一个。
  3. 同一时刻两个Suvivor Place,即s0和s1中总有一个总是空的。
  4. 年轻代中的对象经历过了多次的垃圾回收就会转移到年老代中。
  5. 当申请不到空间时会抛出 OutOfMemoryError。下面我们简单的模拟一个堆内存溢出的情况:
复制代码
import java.util.ArrayList;
import java.util.List;
/* java -Xms20m -Xmx20m HeapOOM */
public class HeapOOM {
    static class OOMObject {
    }
    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while (true) {
            list.add(new OOMObject());
        }
    }
}
复制代码

 

下面是执行结果:

复制代码
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at HeapOOM.main(HeapOOM.java:13)
复制代码

 

堆内存是我们平时在生产环境中进行性能调优中的一个非常重要的部分。

方法区

方法区与Java堆一样,是各个线程共享的区域,它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译(JIT)后的代码等数据。

虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。

对于JDK1.8之前的HotSpot虚拟机而言,很多人经常将方法区称为我们上图中所描述的永久代,实际上两者并不等价,仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。同时对于其他虚拟机比如IBM J9中是不存在永久代的概念的。

其实,移除永久代的工作从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中,并没完全移除,比如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap,而在JDK1.8之后永久代的该概念也已经不再存在取而代之的是元空间metaspace。

Java虚拟机规范对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是有必要的。根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池

运行时常量池(RuntimeConstantPool)是方法区的一部分。注意我们这里所说的运行时的常量池并仅仅是指Class文件中的常量池,因为JVM可能会进行即时编译进行优化,在运行时将部分常量载入到常量池中。

Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(ConstantPoolTable),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
Java虚拟机对Class文件的每一部分(自然也包括常量池)的格式都有严格的规定,每一个字节用于存储哪种数据都必须符合规范上的要求,这样才会被虚拟机认可、装载和执行。但对于运行时常量池,Java虚拟机规范没有做任何细节的要求。不过,一般来说,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。
运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只能在编译期产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的intern()方法。
既然运行时常量池是方法区的一部分,自然会受到方法区内存的限制,当常量池无法再申请到内存时会抛出OutOfMemoryError异常。

程序计数器

程序计数器(ProgramCounterRegister)的作用可以看做是当前线程所执行的字节码的行号指示器。
由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。 

Java虚拟机栈

与程序计数器一样,Java虚拟机栈(JavaVirtualMachineStacks)也是线程私有的,用通俗的话讲它(或者说是虚拟机栈中的局部变量表部分)就是我们常常听说到堆栈中的那个“栈内存”。

局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。其中64位长度的long和double类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表(局部变量表需要的内存在编译期间就确定了所以在方法运行期间不会改变大小),操作数栈,动态链接,方法出口等信息。每一个方法从调用至出栈的过程,就对应着栈帧在虚拟机中从入栈到出栈的过程。

在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

本地方法栈

本地方法栈(NativeMethodStacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

直接内存

直接内存(DirectMemory)并不是虚拟机运行时数据区的一部分,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。
在JDK1.4中新加入了NIO(NewInput/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括RAM及SWAP区或者分页文件)的大小及处理器寻址空间的限制。服务器管理员配置虚拟机参数时,经常会忽略掉直接内存,使得各个内存区域的总和大于物理内存限制(包括物理上的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。


Java虚拟机(Java VirtualMachine 简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一。

JVM内存模型

 1.方法区和堆是所有线程共享的数据区

1) 堆:存放对象的实例
2) 方法区:存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码
3) 运行时常量池: 用于存放编译期生成的各种字面量和符号引用
 
2.程序计数器、虚拟机栈、本地方法栈是线程隔离的数据区
4) 程序计数器:当前线程所执行字节码的行号指示器
5) 虚拟机栈:描述Java方法执行的内存模型,每个方法被执行时都会创建一个栈帧,用于存储变量表、操作栈、动态连接、方法出口等信息
6) 本地方法栈:和虚拟机站作用相似,本地方法栈是为虚拟机使用到native方法服务。虚拟机栈则为虚拟机执行Java方法服务。
ps. native方法常用于两种情况 : (1) 在方法中调用一些不是由java语言写的代码;(2)在方法中用java语言直接操纵计算机硬件
参考 : JVM初探 - JVM内存模型 (http://blog.youkuaiyun.com/zjf280441589/article/details/53437703)
 
java堆内存(http://www.jianshu.com/p/6d1cbe38a54b)
 
 

何时回收-对象生死判定

1、 引用计数法:很难解决对象之间相互循环引用问题
2、 根搜索算法(GC Roots Tracing):以GCRoots作为起点,如果从GCRoots到一个对象不可达,则该对象是可回收对象
[举例]如下图:  Object5、6、7 虽然互有关联, 但它们到GC Roots是不可达的, 因此也会被判定为可回收的对象:
参考 : JVM内存分配、GC原理与垃圾回收器 (http://www.importnew.com/23035.html)
 

GC原理- 垃圾收集算法 

1、 新生代 - 标记复制算法 : 直接把未清理的对象移动到新的内存,就不会有碎片了(代价小,只要修改堆头指针就可以,但是浪费的内存很多)
  该算法的核心是 将可用内存按容量划分为大小相等的两块, 每次只用其中一块, 当这一块的内存用完, 就将还存活的对象复制到另外一块上面, 然后把已使用过的内存空间一次清理掉.

  现代商用VM的新生代均采用复制算法, 但由于新生代中的98%的对象都是生存周期极短的, 因此并不需完全按照1∶1的比例划分新生代空间, 而是将新生代划分为一块较大的Eden区和两块较小的Survivor区(HotSpot默认Eden和Survivor的大小比例为8∶1), 每次只用Eden和其中一块Survivor. 当发生MinorGC时, 将Eden和Survivor中还存活着的对象一次性地拷贝到另外一块Survivor上, 最后清理掉Eden和刚才用过的Survivor的空间. 当Survivor空间不够用(不足以保存尚存活的对象)时, 需要依赖老年代进行空间分配担保机制, 这部分内存直接进入老年代.

 

2、老年代 - 标记清理算法:直接清理会产生很多碎片

该算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象(可达性分析), 在标记完成后统一清理掉所有被标记的对象.

该算法会有以下两个问题:
1. 效率问题: 标记和清除过程的效率都不高;
2. 空间问题: 标记清除后会产生大量不连续的内存碎片, 空间碎片太多可能会导致在运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集.

 

3.老年代 - 标记整理算法:让存活的对象都往前面移动,排除碎片(代价大,移动过多,不浪费内存)

 
4.分代收集算法:当发现剩余对象少时,直接使用标记复制算法,否则使用标记整理算法
参考 : JVM内存分配、GC原理与垃圾回收器 (http://www.importnew.com/23035.html)
 

JAVA对象的强引用,软引用,弱引用和虚引用

1、 强引用(Strong Reference):不能回收
  以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
2、 软引用(Soft Reference):当内存不够用的时候可以回收
  如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
  软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。
3、 弱引用(Weak Reference):下一次垃圾回收就会被回收

  如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 
    弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

4、虚引用(Phantom Reference):无法通过虚引用得到一个对象,唯一的目的就是为了被回收时收到通知

  "虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

  虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

基于STM32F103C8T6单片机设计CAN接口8路继电器控制板硬件(原理图+PCB)+软件源码 基于STM32F103C8T6单片机设计CAN接口8路继电器控制板硬件(原理图+PCB)+软件源码,仅供学习及设计参考。 阅读详情

相关推荐

Navicat Premium 12 永久激活保姆级教程(附最新补丁下载)

本文详细介绍了Navicat Premium 12的高效使用方法,从安装配置到高级功能应用,帮助用户充分发挥这款数据库管理工具的全部潜力。内容包括数据库连接管理、数据查询与编辑、数据同步与结构对比等核心功能,以及性能优化和最佳实践建议,提升数据库管理效率。

weixin_28834765的博客 643

【JVM】JVM内存模型详解

JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够“一次编译,到处运行的”原因。方法区存储的内容有:类型信息(比如类全称、父类全称)、域信息(域名称、域修饰符private等)、方法信息(方法名称、方法修饰符、返回类型等)、字面量(字面量包括文本字符串、八种基本类型的值 、被声明为final的常量等)。Java虚拟机栈是当前线程在执行方法时存储所需的数据、指令、返回地址的一种栈结构(先进后出)。

Money、坤的博客 1万+

SMETANA 安装使用教程

关于SMETANA的安装和简单使用信息

qq_44940977的博客 1169

深度解析JVM内存模型

q

xiaolinzi176的博客 3714

汽车ECU开发必看:AUTOSAR存储管理模块NvM的5个实战技巧

本文聚焦汽车ECU开发中AUTOSAR存储管理模块NvM的实战应用,分享了五个源自量产项目的核心技巧。内容涵盖Class 3配置的精细调优、稳健冗余策略的构建、读写性能的毫秒级优化、典型工程问题的解决方案以及高效的集成测试方法,旨在帮助开发者规避常见陷阱,实现可靠、高效的存储方案。

weixin_29192211的博客 275

QGIS v3.28 高效加载OSM在线地图的三种实用方法

本文详细介绍了在QGIS v3.28中高效加载OSM在线地图的三种实用方法:通过XYZ Tiles直接连接、使用QuickMapServices插件以及配置WMS/WTMS服务。针对每种方法提供了具体操作步骤、常见问题解决方案和性能优化建议,帮助用户根据需求选择最适合的方案,提升GIS工作效率。

weixin_29233333的博客 433

图解JVM--(四)内存模型

内存模型 java 内存模型 很多人将【java 内存结构】与【java 内存模型】傻傻分不清,【java 内存模型】是 Java Memory Model(JMM)的意思。 简单的说,JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序性、和原子性的规则和保障 1.原子性 问题提出,两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是...

chenhanhao0000的博客 436

Qt 5.15.2静态编译避坑实录:MinGW 32位版从源码到Creator配置的全流程踩坑总结

本文详细介绍了Qt 5.15.2 MinGW 32位版本的静态编译全流程,包括环境准备、配置参数优化、编译过程监控及安装后配置。重点解决了静态编译中的常见问题,如参数顺序敏感、路径引号问题等,并提供了性能对比实测数据,帮助开发者高效完成静态编译。

weixin_26749245的博客 271

【JVM】JVM内存模型(详细)

JVM内存模型(详细)

酷酷的馫博客 5万+

代码审计工具学习之Seay(安装以及初步认识)

目录 1.1名词解释 1.2代码审计的重要性 1.3代码审计的步骤 1.4代码审计的内容 1.5常见的代码审计工具 2 Seay 2.1什么是Seay 2.2Seay的安装过程 3典型漏洞分析 3.1什么是命令注入漏洞 3.2 如何理解命令注入漏洞 3.3 如何防御命令注入漏洞 4 利用工具对命令注入漏洞进行分析 4.1DVWA靶场命令注入漏洞分析 4.2 Pikachu靶场命令注入漏洞分析 1.1名词解释 软件代码审计是对编程项目中源代码的全面...

weixin_52515588的博客 2万+

详解YOLOv8网络结构/环境搭建/数据集获取/训练/推理/验证/导出/部署

YOLO(You Only Look Once)系列算法因其高效、准确等特点而备受瞩目。由2023年Ultralytics公司发布了YOLO的最新版本YOLOv8是结合前几代YOLO的基础上的一个融合改进版。本文YOLOv8网络结构/环境搭建/数据集获取/训练/推理/验证/导出/部署,从网络结构的讲解从模型的网络结构讲解到模型的部署都有详细介绍,同时在本专栏中还包括YOLOv8模型系列的改进包括个人提出的创新点,传统卷积、注意力机制、损失函数的修改教程,能够帮助你的论文获得创新点。

Snu77的博客 8万+

关于JVM内存模型的理解

一、概念 1、JVM内存模型 首先老规矩,祭上一张自己画的内存模型图 画的比较简陋,简单介绍一下,整个JVM占用的内存可分为两个大区,分别是线程共享区和线程私有区,线程共享区和JVM同生共死,所有线程均可访问此区域;而线程私有区顾名思义每个线程各自占有,与各自线程同生共死。这两个大区内部根据JVM规范定义又分为以下几个区: 方法区(Method Area) 方法区主要是放一下...

菜头君的博客 1万+

WPF+MVVM案例实战(一)- 设备状态LED灯变化实现

采用WPF+MVVM框架实现,MVVM框架使用CommunityToolkit.Mvvm 依赖包,代码案例部署了三个LED灯,按照红黄绿三色后台自动刷新状态进行变化,根据后台数据不同,UI层显示不同颜色。

lingshuangcanxue 1382

一图理解JVM内存模型

该图只是用于理解JVM的内存模型的初步,接下来我会对JVM内存模型更加详细的学习和记录。

一点一滴得积累 262

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

深入理解JVM(一):什么是JVM?什么是JVM内存模型?

01 前言 本次将对jvm有更深入的学习,我们不仅要让程序能跑起来,而且是可以跑得更快!可以分析解决在生产环境中所遇到的各种“棘手”的问题,比如运行的应用卡住了,日志不输出,程序没有反应,CPU负载突然升高,多线程应用下,如何分配线程数量等。 02 JVM介绍 2.1 什么是JVM? ​ 作为java工程师,对于jvm肯定不陌生。JVM是Java Virtual Machine的缩写,通俗来说也就是运行java代码的容器。当项目启动时,会根据jvm相关配置参数,在计算机的内存中开启一...

mf97532的博客 1203

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

解析JVM内存模型:一文带你深入理解JVM内存模型

我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等待成本,但是随着CPU的发展,内存的读写速度也远远跟不上CPU的读写速度,因此,为了解决这一纠纷,CPU厂商在每颗CPU上加入了高速缓存,用来缓解这种症状,因此,现在CPU同内存交互就变成了下面的样子。 同样,根据摩尔定律,我们知道单核 CPU的主频不可能无限制的增长,要想很多的提升新能,需要多个处理器

m0_63551359的博客 241

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

关于JVM内存模型和堆内存模型的理解

JAVA的两种内存模型,JVM内存模型,堆内存模型

u013367040的博客 1248

对于jvm内存模型的理解

在面试的时候,经常会被别人问到JVM内存模型,在B站也看过很多大牛的讲解,最后总结出来了一个JVM的内存模型。 在xxx.class文件被执行时候,会被调用javac编译,存入到JVM虚拟机当中,而JVM虚拟机中又包含本地方法栈、线程栈、堆、元空间(以前是方法区,后来好像是jdk1.8之后被改成了元空间永久存储)和程序计数器。 本地方法栈:即为加了native关键词的变量存放的地方,这里一般都是用其他语言编写的局部变量的值 堆:存放对象的地方 ...

qq_45705712的博客 225

深入理解 JVM 内存模型

在 JDK 8 及以后版本中,JVM 内存模型经历了重大改进,摒弃了容易导致内存溢出的"永久代"(PermGen),转而采用更灵活的"元空间"(Metaspace)。JVM 内存模型(JVM Memory Model)是 Java 虚拟机规范中定义的一套完整的内存管理架构,它规范了 Java 程序运行时的内存分配、使用和回收机制。线程私有区域的特点是各个线程都有自己的独立副本,这些区域的内存管理相对简单,因为线程结束后会自动释放,无需垃圾回收机制介入。: 当线程请求的栈深度超过虚拟机允许的最大深度时抛出。

Toroto5的博客 1779

深入理解JVM——JVM内存模型

深入理解JVM——JVM内存模型## JVM内存模型 即Java虚拟机(Java Virtual Machine=JVM)。Java虚拟机的内存空间分为五个部分,分别是: 程序计数器 Java虚拟机栈 本地方法栈 堆 方法区 下面对这五个区域展开深入介绍。 1.程序计数器 1.1 什么是程序计数器? 程序计数器是一块较小的内存空间,可以把它看作当前线程正在执行的字节码的行号指示器。也就是说,程序计数器里面记录的是当前线程正在执行的那一条字节码指令的地址。 注:但是,如果当前线程正在执行的是一个本地方法,

qq_43262128的博客 216

说下对JVM内存模型的理解

说下对JVM内存模型的理解

java1234的博客 667

[java基础]对jvm内存模型理解

今天来说一说java内存模型,因为jvm就是运行在内存里的,所以内存模型全部是存在内存里的。 jvm内存模型主要分为五大区域,程序计数器,本地方法栈,java栈区,方法区,和堆区。下面一个一个来看下。 灰色是区域是线程独有的,它包括是java栈区,本地方法栈和程序计数器都,而堆区和方法区是线程公有的。 1.程序计数器 程序计数器,它是用来存储java的程序的当前执行到的内存地址(你可以理解为程序...

慕容田雨的专栏 243

对JVM内存模型的理解

JVM内存模型: JVM会为每个线程分配独立的空间,用来进行本线程的运算。因此内存模型构成有线程独有的,也有线程共享的。 程序计数器(PC) 线程独有的,是一块较小的内存空间。 记录本线程下一步要执行的指令,通过改变PC值来运行不同行的字节码。 栈(stack) 线程独有的,在线程启动时系统就会分配一个连续的、大小固定的内存空间,这个空间大小可以配置。简单理解就是存储线程运行时需要的引用...

xuyilin3310的博客 333

JVM内存模型的理解

JVM内存模型图 **方法区的堆是线程共有的,虚拟机栈、本地方法栈和程序计数器是线程私有的** 程序计数器 程序计数器是线程私有的,是一块很小的内存空间,可以看作当前线程的行号指示器 程序计数器的主要两个作用: 1、字节码解析器通过改变程序计数器的值来依次读取指令,从而实现代码的流程控制,比如:顺序执行、选择、循环、异常处理等 2、在多线程并发的情况下,程序计数器记录当前线程执行的位置,当线程再切换回来的时候可以知道当前线程所在的位置在哪个位置。 虚拟机栈 1、虚拟机栈描述的是java方法执行的内存模型

qq_36363499的博客 634

AI如何帮你彻底理解JVM内存模型

例如输入"创建带滑动条的JVM内存可视化,包含堆、栈、方法区三色区块",就能获得Canvas绘图的初始代码。继续细化要求如"添加New Object按钮,点击后在堆内存生成红色矩形",AI会补充事件监听逻辑。这次实践让我意识到,AI工具不仅能加速开发,更重要的是创造了新的学习方式。以往需要三天实现的演示工具,现在两小时就能完成原型,且效果更生动。学习JVM内存模型时,很多开发者会被抽象的概念困扰。点击部署按钮就能生成可分享的演示链接,学生通过拖拽参数滑块就能看到内存变化,比静态图示直观十倍。

GoldEagle19的博客 526
上一篇: MySQL 高级
下一篇: BIO、AIO与NIO的区别
Mask_V
博客等级 码龄9年 7粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值