Java内存区域怎么划分的?内存结构是什么样子的?
内存结构
2 个回答
自己喜欢的东西,就不要问别人好不好。粑粑运行时数据区域包含以下五个区域:程序计数器,Java虚拟机栈,本地方法栈,堆,方法区(其中前三个区域各线程私有,相互独立,后面两个区域所有线程共享)  ### 线程私用的部分(Java虚拟机栈,本地方法栈,程序计数器) #### Java虚拟机栈 执行一个Java方法时,虚拟机都会创建一个栈帧,来存储局部变量表,操作数栈等,方法调用完毕后会对栈帧从虚拟机栈中移除。 局部变量表中存储了Java基本类型,对象引用(可以是对象的存储地址,也可以是代表对象的句柄等)和returnAddress类型(存储了一条字节码指令的地址)。 #### 本地方法栈 本地方法栈与Java虚拟机栈类似,只不过是执行Native方法(C++方法等)。 #### 程序计数器 计数器存储了当前线程正在执行的字节码指令的地址(如果是当前执行的是Native方法,那么计数器为空),字节码解释器就是通过改变计数器的值来选取下一条需要执行的字节码指令。程序计数器是线程私有的,便于各个线程切换后,可以恢复到正确的执行位置。 ### 线程共享的部分(堆,方法区) #### Java 堆 堆存储了几乎所有对象实例和数组,是被所有线程进行共享的区域。在逻辑上是连续的,在物理上可以是不连续的内存空间(在存储一些类似于数组的这种大对象时,基于简单和性能考虑会使用连续的内存空间)。 #### 方法区 存储了被虚拟机加载的类型信息,常量,静态变量等数据,在JDK8以后,存储在方法区的元空间中(以前是存储在堆中的永久代中,JDK8以后已经没有永久代了)。 运行时常量池是方法区的一部分,会存储各种字面量和符号引用。具备动态性,运行时也可以添加新的常量入池(例如调用String的intern()方法时,如果常量池没有相应的字符串,会将它添加到常量池)。 - 在 Java 7 及之前,方法区通常被称为“永久代”(Permanent Generation,简称 PermGen),是堆的一部分。 - 从 Java 8 开始,方法区被移到了一个叫“元空间”(Metaspace)的区域,位于本地内存中,不再是堆的一部分。 #### 直接内存区(不属于虚拟机运行时数据区) 直接内存区不属于虚拟机运行时数据区的一部分。它指的是使用Native方法直接分配堆外内存,然后通过Java堆中的DirectByteBuffer来对内存的引用进行操作(可以避免Java堆与Native堆之间的数据复制,提升性能)。编辑于 2024-02-26 03:33 •IP属地 北京举报评论收藏
让心中无事,让细水长流。海波东### Java 内存结构 #### 线程共享区域 1. **Java 堆(Heap)** - **描述**:Java 堆是 JVM 管理的内存中最大的一块。它是所有线程共享的内存区域,在虚拟机启动时创建。 - **用途**:主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 2. **方法区(Method Area)** - **描述**:方法区与 Java 堆一样,是各个线程共享的内存区域。 - **用途**:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 #### 线程私有区域 1. **程序计数器(Program Counter Register)** - **描述**:程序计数器是一块较小的内存空间。 - **用途**:作用是当前线程所执行的字节码的行号指示器。 2. **JVM 栈(JVM Stacks)** - **描述**:JVM 栈是线程私有的,其生命周期与线程相同。 - **用途**:描述的是 Java 方法执行的内存模型。每个方法被执行的时候都会同时创建一个栈帧(Stack Frame),用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 3. **本地方法栈(Native Method Stacks)** - **描述**:本地方法栈与 JVM 栈类似,也是线程私有的。 - **用途**:区别在于 JVM 栈为虚拟机执行 Java 方法(字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 通过以上划分,JVM 内存结构可以清晰地描述不同内存区域的用途和管理方式。线程共享区域主要用于存放类信息和对象实例,而线程私有区域则用于管理方法的执行和线程状态。这种设计能够有效地管理和优化内存使用,提高 JVM 的执行效率和稳定性。发布于 2023-09-17 19:35 •IP属地 宁夏举报评论收藏
公众号进入网站体验更佳

