JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )


堆区:

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身

栈区:

1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中。
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

栈帧:一个栈帧随着一个方法的调用开始而创建,调用完成而销毁。每个方法从调用到结束就对于一个栈桢在虚拟机栈中的入栈和出栈过程
JVM栈只对栈帧进行存储,压栈和出栈操作。Java栈是Java方法执行的内存模型。

每个方法涉及的局部变量表和操作数栈的大小取决于每个具体的方法,但是大小在编译后便已确定,而且已经包含在class文件中。

  • 每个JVM线程有一个私有栈,栈在线程创建的同时被创建。
  • 栈由许多帧组成,也叫 “栈帧”
  • 每次方法调用都会创建一个栈帧

方法区:

1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

为了更清楚地搞明白发生在运行时数据区里的黑幕,我们来准备2个小道具(2个非常简单的小程序)。

 1 AppMain.java
2 public class AppMain{//运行时, jvm 把appmain的信息都放入方法区
3 public static void main(String[] args){ //main 方法本身放入方法区。
4 Sample test1 = new Sample( " 测试1 " ); //test1是引用,所以放到栈区里,Sample是自定义对象应该放到堆里面
5 Sample test2 = new Sample( " 测试2 " );
6 test1.printName();
7 test2.printName();
8 }
9 }
10
11 Sample.java
12 public class Sample { //运行时, jvm 把appmain的信息都放入方法区
13 /** 范例名称 */
14 private String name; //new Sample实例后,name引用放入栈区里,name对象放入堆里
15 /** 构造方法 */
16 public Sample(String name)
17 {
18 this .name = name;
19 }
20 /** 输出 */
21 public void printName() //print方法本身放入 方法区里。
22 {
23 System.out.println(name);
24 }
25 }
 

类的加载过程

系统收到了我们发出的指令,启动了一个Java虚拟机进程,这个进程首先从classpath中找到AppMain.class文件,读取这个文件中的二进制数据,然后把Appmain类的类信息存放到运行时数据区的方法区中。这一过程称为AppMain类的加载过程。

接着,Java虚拟机定位到方法区中AppMain类的Main()方法的字节码,开始执行它的指令。这个main()方法的第一条语句就是:
Sample test1=new Sample(“测试1”);
让java虚拟机创建一个Sample实例,使引用变量test1引用这个实例。

Java虚拟机执行过程

跟踪一下Java虚拟机,看它是怎么来执行这个任务的:
1、建立一个Sample实例:到方法区,先找到Sample类的类型信息。结果这会儿的方法区里还没有Sample类呢。于是,Java虚拟机发扬“自己动手,丰衣足食”,立马加载了Sample类,把Sample类的类型信息存放在方法区里。
2、Java虚拟机在堆区中为一个新的Sample实例分配内存, 这个Sample实例持有着指向方法区的Sample类的类型信息的引用。这里所说的引用,实际上指的是Sample类的类型信息在方法区中的内存地址【堆中Sample实例持有着指向方法区的Sample类的内存地址】,其实,就是有点类似于C语言里的指针啦~~,而这个地址呢,就存放了在Sample实例的数据区里。
3、 在JAVA虚拟机进程中,每个线程都会拥有一个方法调用栈,用来跟踪线程运行中一系列的方法调用过程,栈中的每一个元素就被称为栈帧,每当线程调用一个方法的时候就会向方法栈压入一个新帧。这里的帧用来存储方法的参数、局部变量和运算过程中的临时数据。

位于“=”前的Test1是一个在main()方法中定义的变量,可见,它是一个局部变量,因此,它被会添加到了执行main()方法的主线程的JAVA方法调用栈中。而“=”将把这个test1变量指向堆区中的Sample实例,也就是说,它持有指向Sample实例的引用。

接下来,JAVA虚拟机将继续执行后续指令,在堆区里继续创建另一个Sample实例,然后依次执行它们的printName()方法。当JAVA虚拟机执行test1.printName()方法时,JAVA虚拟机根据局部变量test1持有的引用,定位到堆区中的Sample实例,再根据Sample实例持有的引用,定位到方法区中Sample类的类型信息,从而获得printName()方法的字节码,接着执行printName()方法包含的指令。

深入理解JVM(二)JVM内存模型

JVM 内存 (堆(heap)、栈(stack)和方法区(method) )的更多相关文章

  1. (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)

    [color=red][/color]<一> 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈 ...

  2. Java里的堆(heap)栈(stack)和方法区(method)

    基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 . 方法 ...

  3. [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...

  4. JVM 内存初学 堆(heap)、栈(stack)和方法区(method)

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...

  5. 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...

  6. JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )(转载)

    想想面试的时候很多会问jvm这方面的问题虽然还是菜鸟不太能用到现在但是还是了解一下, 找资料的时候看见个大佬写的很好转载到这方便以后自己复习和给大佬做宣传 以下为大佬的博客原文: 这两天看了一下深入浅 ...

  7. JVM内存模型——堆(heap)、栈(stack)和方法区(method)

      JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...

  8. java虚拟机知识和 内存 堆(heap)、栈(stack)和方法区(method)

    1.虚拟机实例 每个java程序都运行在自己的java虚拟机实例中,运行三个java程序就会得到三个虚拟机实例 守护线程(虚拟机自己使用,比如说执行垃圾收集任务的线程) 非守护线程(java初试线程, ...

  9. java面试之----堆(heap)、栈(stack)和方法区(method)

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的 ...

随机推荐

  1. [Golang]一些书城项目中出现错误的原因和解决办法(一)

    跟着B站尚硅谷的GoWeb教程写书城项目,整理一下自己写的时候出现的错误和解决办法. 错误一:cartItem中只能加入一种书,SQL语句没有问题,但是购物车中的总金额和总数量正确: 原因:cartI ...

  2. (tamcat控制台乱码)在idea中运行toncat后控制台出现乱码的情况解决办法(教程附图)。

    详细教程: (tamcat控制台乱码)在idea中运行toncat后控制台出现乱码的情况解决办法(教程附图)._IT打工酱的博客-CSDN博客

  3. 『德不孤』Pytest框架 — 8、Pytest断言

    目录 1.什么是断言 2.Pytest断言 3.Pytest的断言方式及应用场景 (1)使用assert语句 (2)断言预期的异常 (3)拓展 4.优化断言 5.使用标记检查异常 1.什么是断言 对于 ...

  4. 关于GDPR的六大理解

    通用数据保护条例(GDPR)于2018年5月生效,根据法律条文,英国几乎所有企业都需要遵守该规定.然而,人们对法规本身及其对组织的意义仍存在一些误解.这可能会导致一些错误的决定. 通用数据保护条例(G ...

  5. 举例说明EF CORE中模型之间的一对多、多对多关系的实现

    该例子是我临时想出来的,不具有任何的实际意义.类图如图1所示. 图1 类代码: [Table("student")] public class Student { public i ...

  6. Java课程设计---实现登录(2)

    前面已经完成了登录界面的设计,单击确认按钮可以获取输入的用户名和密码,下面来将演示实现真实的登录(输入值和数据库的比对) 1.设计"登录服务" 通常我们根据业务关系,对相应的操作人 ...

  7. QT:异常、错误

    1.Unknown module(s) in QT: xxx 原因1:我们的QT中没有安装这个Module 解决方法:Unknown module(s) 与MaintenanceTool.exe更新. ...

  8. Yarn 命令使用

    windows下安装方法: 1.下载安装包:直接下载.msi安装文件安装,下载地址 2.使用Chocolatey进行安装:Chocolatey是一个windows下的包管理器,可以通过在命令行下输入以 ...

  9. Go基础知识梳理(二)

    Go基础知识梳理(二) 简单函数的定义 //有参数有返回值 func sum(a int, b int) int { return a + b } //无返回值 func sum(a int, b i ...

  10. 开机弹出一下Visual Studio Just-In-Time对话框的问题

    开机弹出一下Visual Studio Just-In-Time对话框 开机弹出一下Visual studio just-in-time对话框,出现一下问题,且点击确定后又弹出第二个对话框, 解决方法 ...