首页 > 系统相关 >Java对象内存图

Java对象内存图

时间:2024-10-09 18:49:53浏览次数:9  
标签:存储 Java 对象 局部变量 数据类型 内存 方法 public

Java的对象内存图

一、Java内存分配介绍

Java 虚拟机(JVM)在执行 Java 程序时会使用多个内存区域

  • 栈:方法运行时所进入的内存,变量也是在这里
  • 堆:new出来的东西会在这块内存中开辟空间并产生地址
  • 方法区:字节码文件加载时进入的内存(class类、main方法等)
  • 本地方法栈
  • 寄存器

1. 堆区(Heap)

  • 用途:
    • 堆区是 Java 中用于动态分配内存的区域。所有的对象实例和数组都在堆中分配。
  • 特点:
    • 堆是共享的,所有线程都可以访问。
    • 垃圾回收器负责自动管理堆内存,回收不再使用的对象。
  • 生命周期:
    • 对象在堆中创建时,只有在没有引用指向该对象时,才会被垃圾回收。

2. 栈区(Stack)

  • 用途:
    • 栈区用于存储局部变量和方法调用的上下文。
  • 特点:
    • 每个线程都有自己的栈,线程之间相互独立。
    • 栈内存采用后进先出(LIFO)原则,方法调用时会将方法的局部变量和参数压入栈中,方法返回时会清除相应的栈帧。
  • 生命周期:
    • 局部变量的生命周期与方法调用的生命周期相同,方法结束后,局部变量会被自动释放。

3. 方法区(Method Area)

  • 用途:
    • 方法区用于存储类的结构信息,包括类的元数据、常量、静态变量和即时编译(JIT)编译后的代码等。
  • 特点:
    • 方法区在 JVM 中是共享的,所有线程都可以访问。
    • 在 HotSpot JVM 中,方法区通常实现为永久代(PermGen)或元空间(Metaspace)。
  • 生命周期:
    • 类的元数据在类被加载时创建,类被卸载时释放。

4. 本地方法栈(Native Method Stack)

  • 用途:
    • 本地方法栈用于支持 Java 中调用的本地方法(Native Method)。本地方法是用其他语言(如 C 或 C++)编写的,并通过 Java Native Interface (JNI) 调用。
  • 特点:
    • 本地方法栈和 Java 栈类似,每个线程都有自己的本地方法栈。
    • 存储本地方法调用的参数、局部变量和返回值。
  • 生命周期:
    • 本地方法栈的生命周期与线程相同,当线程结束时,相关的本地方法栈也会被销毁。

5. 寄存器(Registers)

  • 用途:
    • 寄存器是 CPU 中的高速存储器,用于存储临时数据和指令。JVM 在执行字节码时,常常会使用寄存器来提高执行效率。
  • 特点:
    • 寄存器的数量相对较少,访问速度非常快。
    • JVM 在执行字节码时,将某些运算的结果直接存储在寄存器中,而不是在栈中进行操作。
  • 使用:
    • JVM 的具体实现会利用寄存器进行优化,尤其是在进行算术运算和逻辑运算时。

总结:

Java 虚拟机 在执行 Java 程序时,会在这些不同的内存区域中管理内存:

  • 堆区:存储对象实例和数组,进行动态内存分配。
  • 栈区:存储方法调用的局部变量和参数,支持方法的调用与返回。
  • 方法区:存储类的结构信息和静态数据,支持反射和类的加载。
  • 本地方法栈:用于支持调用本地方法,存储本地方法的局部变量和参数。
  • 寄存器:用于存储临时数据和指令,提高执行效率。

二、一个对象的内存图

示例代码:

public class Student {
    String name;
    int age;
    
    public void study() {
        System.out.println("好好学习");
    }
}
public class TestStudent {
    public static void main(String[] args) {
        Student s= new Student();
        System.out.println(s);
        System.out.println(s.name + "..." + s.age);
        s.name = "阿明";
        s.age = 21;
        System.out.println(s.name + "..." + s.age);
        s.study();
    }
}

在这里插入图片描述

一个对象的内存图的虚拟机执行过程:

  1. 先在方法区加载TestStudent类的字节码文件,将main方法进行临时存储
  2. 此时main方法会被加载到栈里
  3. 在方法区加载Student类文件,临时存储
  4. Student s——在栈区的main方法中开辟以s命名的内存空间
  5. new Student()——在堆区开辟一个空间,并将Student类里面的所有成员变量拷贝过去,并获得所有成员方法的地址
  6. 默认初始化、显示初始化、构造方法初始化成员变量
  7. 将堆中的地址值赋值给栈区的局部变量s
  8. System.out.println(s)——即打印s的地址值
  9. 后面的代码根据s的地址对在堆区的成员变量的值进行操作
  10. s.study()在调用堆区的方法地址,再找的方法区中进行操作,此时该方法会被加载进栈
  11. 进行study方法里的System.out.println("好好学习")操作
  12. study方法执行完毕,退出栈区,main方法也执行完毕,退出栈区
  13. 堆中的内存地址则没地调用,堆的内容也会被系统回收

三、二个对象的内存图的虚拟机执行过程:

和一个对象的内存图相比,方法区不必再次加载,堆区开辟新的空间即可,且两个空间互不影响


四、两个引用指向同一个对象:

示例代码:

public class Student {
    String name;
    int age;
    
    public void study() {
        System.out.println("好好学习");
    }
}
public class TestStudent {
    public static void main(String[] args) {
        Student stu1= new Student();
        stu1.name = "阿明";
        Student stu2 = stu1;
        stu2.name = "阿珍"
        System.out.println(stu1.name + "..." + stu2.name);
        stu1 = null;
        System.out.println(stu1.name);
        System.out.println(stu2.name);
        stu2 = null;
    }
}

不同在Student stu2 = stu1相当于将stu1保存的堆区new出的地址赋值给stu2,共同操作该堆区的空间,stu1 = null——stu1指向的方法消失,但还可以通过stu2操作,但当stu2 = null时堆区的空间不被调用,则会消失,堆区被清空,栈区的方法也操作完毕,出栈


五、基本数据类型和引用数据类型

​ 在编程中,数据类型通常分为基本数据类型(或原始数据类型)和引用数据类型。

基本数据类型

  1. 定义:基本数据类型是语言内置的类型,通常直接表示简单的值。

  2. 值存储:基本数据类型的变量直接存储数据的值。

  3. 内存分配:在栈内存中分配,存储效率高。

  4. 示例:

    • 整数(如 int
    • 浮点数(如 float, double
    • 字符(如 char
    • 布尔值(如 boolean

引用数据类型

  1. 定义:引用数据类型是用户定义的类型,包括对象和数组。

  2. 值存储:引用数据类型的变量存储的是对象的引用(地址),而不是对象本身的值。

  3. 内存分配:在堆内存中分配,通常占用更多内存。

  4. 示例:

    • 类(如 String, ArrayList
    • 接口
    • 数组(如 int[]

主要区别总结

  • 存储方式:基本数据类型存储值,引用数据类型存储地址。
  • 内存管理:基本数据类型在中,引用数据类型在中。
  • 性能:基本数据类型通常更高效,因为它们的内存占用较小。

六、this的内存原理

this的作用:

  1. 区分局部变量和成员变量
  2. 用于构造函数的重载
public class Example {
    private int value;

    public Example(int value) {
        this.value = value; // 指向当前实例的变量
    }

    public Example() {
        this(5); // 调用带参数的构造函数
    }
}

解释

  • 当你创建一个 Example 对象时,可以使用 new Example(10) 创建一个有参数的实例,this.value 将被赋值为 10。
  • 如果使用 new Example(),则会调用无参构造函数,它内部又调用了带参数的构造函数 this(5),因此 value 将被初始化为 5。

this的本质:

所在方法调用者的地址值,管理调用者的数据


七、成员变量和局部变量的区别

1. 定义

  • 成员变量:也称为实例变量,属于类的实例,定义在类的内部但在方法外部。
  • 局部变量:定义在方法、构造函数或代码块内部,只在该特定作用域内有效。

2. 作用域

  • 成员变量:在整个类中可访问,所有实例方法都可以访问,甚至可以通过对象实例访问。
  • 局部变量:仅在定义它们的方法或代码块中有效,超出该作用域后无法访问。

3. 生命周期

  • 成员变量:对象创建时分配内存,直到对象被垃圾回收时,成员变量的生命周期持续存在。
  • 局部变量:在方法或代码块执行时分配内存,方法执行完毕后被销毁。

4. 默认值

  • 成员变量:如果没有显式初始化,成员变量会被默认初始化为其类型的默认值(例如,整型为 0,布尔型为 false,引用类型为 null)。
  • 局部变量:必须显式初始化,未初始化的局部变量无法使用,编译器会报错。

5.内存位置不同

  • 成员变量:堆内存(对象里面)
  • 局部变量:栈内存(方法里面)

6. 访问修饰符

  • 成员变量:可以使用访问修饰符(如 public, private, protected) 来控制访问权限。
  • 局部变量:没有访问修饰符,仅在其所在的方法内有效。
示例:
public class Example {
    // 成员变量
    private int memberVariable = 10;

    public void method() {
        // 局部变量
        int localVariable = 5;

        System.out.println("Member Variable: " + memberVariable); // 可以访问
        System.out.println("Local Variable: " + localVariable);   // 可以访问
    }

    public void anotherMethod() {
        // System.out.println(localVariable); // 编译错误:局部变量在此不可访问
    }
}

此篇内容结束

标签:存储,Java,对象,局部变量,数据类型,内存,方法,public
From: https://blog.csdn.net/2302_81034736/article/details/142774936

相关文章

  • 0基础学Java之Day02(上午完整版)
    一、扩展Hello.java1.详解代码/**作者:zzj时间:2024年10月9日*/​//公有的类叫做HellopublicclassHello{​//公有的静态的无返回值的方法叫做main--这种固定写法的方法叫做主方法publicstaticvoidmain(String[]args){​//输出语句(......
  • 0基础学Java之Day02(下午完整版)
    五、Java的体系划分JavaSE--J2SE--核心版本JavaEE--J2EE--企业版本(做服务器)JavaME--J2ME--微型版本(做移动端--已弃用)学习路线:后端程序员:JavaSE、JavaEE移动端程序员:JavaSE、JavaME-------(已弃用)Android移动端程序员:JavaSE、AndroidSDKIOS移动端程序......
  • 【Java】反射
    Java中的反射机制动态代理反射允许对封装类的字段,方法和构造函数的信息进行编程访问==》反射允许对成员变量,成员方法和构造方法的信息进行编程访问基本操作:获取(获取class对象【字节码对象】)+解剖成员变量Field——修饰符、名字、类型、赋值构造方法Constructor......
  • java计算机毕业设计保险业务管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着经济的飞速发展和人民生活水平的日益提高,保险作为一种风险转移和保障机制,在现代社会中扮演着愈发重要的角色。传统的保险业务处理方式往往依赖于......
  • java计算机毕业设计高校社团信息管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着高等教育的快速发展,高校学生社团作为校园文化的重要组成部分,日益成为学生综合素质提升、兴趣培养及社交拓展的重要平台。然而,传统的手工管理方式......
  • 06 Java 案例
    一、买飞机票1.需求用户购买机票时,机票原价会按照淡季、旺季,头等舱还是经济舱的情况进行相应的优惠,优惠方案如下:5-10月为旺季,头等舱9折,经济舱8.5折;11月到来年4月为淡季,头等舱7折,经济舱6.5折,请开发程序计算出用户当前机票的优惠价。2.分析方法是否需要接收数据? 需要接收......
  • Java中泛型的学习
    泛型目录泛型什么是泛型泛型方法泛型的作用泛型的特性泛型的使用普通泛型静态泛型方法什么是泛型Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类......
  • java中Set的介绍与实现:HashSet、LinkedHashSet、TreeSet
    在Java中,Set是Collection接口的一个子接口,它是一个不包含重复元素的集合,且通常不保证维护元素的有序或迭代顺序。Set接口主要用于确保集合中每个元素的唯一性。Set接口的主要方法:booleanadd(Ee):将指定的元素添加到此集合中(如果它尚未在集合中)。booleanremove(Objec......
  • 查询计算移出数据库用 Java 太慢咋办
    很多现代应用会把数据计算和处理任务从数据库移出来采用Java实现,这样能获得架构上的好处,而且Java有完善过程处理能力,应对日益复杂的业务逻辑比SQL更得心应手(虽然代码不短)。不过,我们常常会发现,这些Java代码计算和处理数据的性能不如人意,赶不上数据库里的SQL。按说,作为......
  • java计算机毕业设计大型企业健康系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在当今社会,随着工作节奏的加快和生活压力的增大,大型企业员工的身心健康问题日益凸显。长期的高压工作环境容易导致员工出现心理健康问题,如焦虑、抑郁......