JVM内存你必须了解的【堆-栈-方法区】(面试必备)

0x01.JVM内存划分关系

JVM体系结构(简单版)

在这里插入图片描述

运行时数据区的主要作用:

区域名称 实际作用
寄存器 保存有当前正在执行的JVM指令的地址。
本地方法栈 为JVM使用到的Native方法服务
方法区 存储可执行的.class文件
堆内存 存储数组或者对象
方法栈 方法运行时使用的内存

本文主要研究运行时数据区中的堆,栈,方法区


0x02.分析一段简单代码,了解数组数组创建过程

  • 看一下下面这段代码:
public stativ void main(String args[]){
	int[] a=new int[5];
	System.out.println(a);
}	
  • 相信大家很容易知道,输出的内容就是a数组在内存中的地址。
  • 那这个地址实际上指的是哪里呢?
  • 我们一起分析一下这个程序的运行流程:

仅分析一下主要new出数组的过程,其它的细节此处省略。

堆栈上的主要执行流程:

1.main方法入栈:

在这里插入图片描述

2.读取new语句,在堆中开辟空间,存储数据:

  • 堆会给数组分配初始值。
    在这里插入图片描述

  • 到这里,我们应该就可以知道,实际的地址是在堆中分配的地址。

0x03.通过堆-栈-方法区,了解对象在内存中存储

  • 再来看一段简单的代码:
  • 一个People类:
public class Peolple{
	String name;
	int age;
	String sex
	
	public void eat{
		System.out.println("吃饭");
	}
}
  • main方法:
public static void main(String args[]){
	Perple people=new People();
	people.name="ATFWUS";
	people.age=18;
	people.sex="man";
	people.eat();
}

内存结构分析(单个对象):

在这里插入图片描述

0x04.细究堆-栈-方法区在内存中的作用

  • 堆和栈的关系用一句话描述就是:栈管运行,堆管存储

1.堆

  • 主要:用来存放程序动态生成的数据

  • 重点:堆是内存中共享的区域,要考虑线程安全的问题。

  • 凡是new出来的对象,都在堆中:

    • 存储的是成员变量。
    • 静态变量存储在方法区。
    • 而成员变量的值存储在常量池中。
    • 成员方法存储在方法区中,是此类所有实现实例共享的。
  • 常量池:

    扫描二维码关注公众号,回复: 11444064 查看本文章
    • 常量池在堆中。
    • JVM为每一个加载的类维护一个常量池。
    • 用于存储成员变量中的数值。

2.栈

  • 栈是线程独享的。每一个线程都有自己的线程栈。

  • 栈的生命周期跟随线程的生命周期。

  • 栈存储的数据:(栈帧)

    • ① 本地变量 : 参数,返回值,方法内的变量;
    • ② 栈操作 : 栈指针(ebp,esp);
    • ③ 栈帧数据 : 类文件、方法等。
  • 栈是方法运行时使用的内存。

3.方法区

  • 供各线程 共享 的运行时内存区域。

  • 存储了每一个类的结构信息。

  • 方法区主要用于存储已经被虚拟机加载的类的信息、常量、静态变量等。

    • 在JVM加载某个类时,会抽取出对应.class文件中类相关的信息并以特定结构存到方法区中,当程序运行时,JVM则会到方法区中去查找使用对应类信息。

猜你喜欢

转载自blog.csdn.net/ATFWUS/article/details/106262974