Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method) 爱被打了一巴掌 2022-08-26 15:25 209阅读 0赞 JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method) **堆区:** 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身. 3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。 **栈区:** 1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。 3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。 4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等. **静态区/方法区:** 1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。 2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。 3.—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 代码实例(转自网络) AppMain.java public class AppMain //运行时, jvm 把appmain的信息都放入方法区 \{ public static void main(String\[\] args) //main 方法本身放入方法区。 \{ Sample test1 = new Sample( " 测试1 " ); //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面 Sample test2 = new Sample( " 测试2 " ); test1.printName(); test2.printName(); \} \} Sample.java public class Sample //运行时, jvm 把appmain的信息都放入方法区 \{ /\*\* 范例名称 \*/ private name; //new Sample实例后, name 引用放入栈区里, name 对象放入堆里 /\*\* 构造方法 \*/ public Sample(String name) \{ this .name = name; \} /\*\* 输出 \*/ public void printName() //print方法本身放入 方法区里。 \{ System.out.println(name); \} \} 代码的执行过程: ![0_1302327673i3Z0.gif][] 系统收到了我们发出的指令,启动了一个Java虚拟机进程,这个进程首先从classpath中找到AppMain.class文件,读取这个文件中的二进制数据,然后把Appmain类的类信息存放到运行时数据区的方法区中。这一过程称为AppMain类的加载过程。 接着,Java虚拟机定位到方法区中AppMain类的Main()方法的字节码,开始执行它的指令。这个main()方法的第一条语句就是: Sample test1=new Sample("测试1"); 语句很简单啦,就是让java虚拟机创建一个Sample实例,并且呢,使引用变量test1引用这个实例。貌似小case一桩哦,就让我们来跟踪一下Java虚拟机,看看它究竟是怎么来执行这个任务的: 1、 Java虚拟机一看,不就是建立一个Sample实例吗,简单,于是就直奔方法区而去,先找到Sample类的类型信息再说。结果呢,嘿嘿,没找到@@,这会儿的方法区里还没有Sample类呢。可Java虚拟机也不是一根筋的笨蛋,于是,它发扬“自己动手,丰衣足食”的作风,立马加载了Sample类,把Sample类的类型信息存放在方法区里。 2、 好啦,资料找到了,下面就开始干活啦。Java虚拟机做的第一件事情就是在堆区中为一个新的Sample实例分配内存, 这个Sample实例持有着指向方法区的Sample类的类型信息的引用。这里所说的引用,实际上指的是Sample类的类型信息在方法区中的内存地址,其实,就是有点类似于C语言里的指针啦~~,而这个地址呢,就存放了在Sample实例的数据区里。 3、 在JAVA虚拟机进程中,每个线程都会拥有一个方法调用栈,用来跟踪线程运行中一系列的方法调用过程,栈中的每一个元素就被称为栈帧,每当线程调用一个方法的时候就会向方法栈压入一个新帧。这里的帧用来存储方法的参数、局部变量和运算过程中的临时数据。OK,原理讲完了,就让我们来继续我们的跟踪行动!位于“=”前的Test1是一个在main()方法中定义的变量,可见,它是一个局部变量,因此,它被会添加到了执行main()方法的主线程的JAVA方法调用栈中。而“=”将把这个test1变量指向堆区中的Sample实例,也就是说,它持有指向Sample实例的引用。 OK,到这里为止呢,JAVA虚拟机就完成了这个简单语句的执行任务。参考我们的行动向导图,我们终于初步摸清了JAVA虚拟机的一点点底细了,COOL! 接下来,JAVA虚拟机将继续执行后续指令,在堆区里继续创建另一个Sample实例,然后依次执行它们的printName()方法。当JAVA虚拟机执行test1.printName()方法时,JAVA虚拟机根据局部变量test1持有的引用,定位到堆区中的Sample实例,再根据Sample实例持有的引用,定位到方法去中Sample类的类型信息,从而获得printName()方法的字节码,接着执行printName()方法包含的指令。 [0_1302327673i3Z0.gif]: /images/20220824/15385818fbce4d2f8c6b05a504fa36be.png
相关 Java虚拟机内存管理:栈区、堆区、方法区理解 在Java虚拟机(JVM)的内存管理中,主要包括三个区域:栈区、堆区和方法区。下面分别介绍这三个区域: 1. 栈区(Stack): - **局部变量**:每个方法都有自 绝地灬酷狼/ 2024年09月10日 16:42/ 0 赞/ 52 阅读
相关 【Java】堆(heap)、栈(stack)和方法区(method) 栈:调用方法将在栈中开辟内存,称为入栈(压栈)。 栈内存存放基本类型值和引用数据类型的地址。 栈内存中的数据,没有默认初始化值,需要手动设置。 方法调用完成,栈内存立即释 ╰半橙微兮°/ 2024年03月30日 03:23/ 0 赞/ 80 阅读
相关 java静态区_Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method)... JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。( 古城微笑少年丶/ 2022年11月02日 06:51/ 0 赞/ 188 阅读
相关 Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method) JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。 爱被打了一巴掌/ 2022年08月26日 15:25/ 0 赞/ 210 阅读
相关 浅析栈区和堆区内存分配的区别 一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢?为了说明这个问题,我们先来看一下内 冷不防/ 2022年08月08日 06:26/ 0 赞/ 194 阅读
相关 JVM的堆(heap)、栈(stack)和方法区(method) JVM主要由类加载器子系统、运行时数据区(内存空间)、执行引擎以及与本地方法接口等组成。其中运行时数据区又由方法区Method Area、堆Heap、Java stack、PC 小灰灰/ 2022年06月13日 13:44/ 0 赞/ 214 阅读
相关 栈区和堆区内存分配区别 一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢?为了说明这个问题,我们先来看 野性酷女/ 2022年06月12日 07:44/ 0 赞/ 232 阅读
相关 面试题汇总--静态存储区、栈区、堆区的区别 一、内存基本构成: 可编程内存分配有3种:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。 二、静态存储区、栈区、堆区的详解 静态存储区:内存在程序编译的 妖狐艹你老母/ 2022年03月17日 10:36/ 0 赞/ 241 阅读
相关 java的堆,栈,静态代码区(常量区) 详解 准备面试的时候突然看到了一个关于java中数据存储的问题,所以搜集了一下资料,感觉不错,分享给大家,转载自:[Java的对,栈,静态代码详解][Java] 一:在 梦里梦外;/ 2022年02月22日 15:42/ 0 赞/ 314 阅读
还没有评论,来说两句吧...