Java中对象几种类型的内存分配(JVM对象储存机制)

简介: Java中对象几种类型的内存分配(JVM对象储存机制)
对象的内存分配—

堆内存:所有使用new关键字创建的对象都在堆内存中

存储对象的变量p(引用)中保存对象的地址,通过变量中的地址访问对象的属性和方法。


当Java程序执行时:

  1. 根据Java程序相关的操作会在内存区域进行空间开辟[栈、堆、方法区]
  2. JVM会向内存申请一块区域进行执行程序
  3. 当第一次使用某个类的时候,就会把这个类的字节码文件加载到放去中
  4. 当调用某个方法时,该方法就会被加载到栈区中,开辟一块新的空间来执行该
  5. 凡是new关键字创建的都会在堆中开辟一段新的空间
  6. 系统中栈空间是无需程序猿进行管理的,因为系统会自动对栈中空间进行回收处理
  7. 引用类型在堆中创建了空间之后,不由系统进行空间回收操作,Java中有一套专门针对堆空间回收操作----叫做GC,GC进行回收时是根据栈中不在引用堆中地址,就进行回收操作[null]
1 单个对象在内存中存储
代码示例
package Task;
public class Student {
    String name;//姓名
    int age;//年龄
    //行为  学习
    public void study(){
        System.out.println("正在努力的学习Java......");
    }
}
//==============================================================================
package Task;
public class StudentTest {
    public static void main(String[] args) {
        //1. 创建Student类的对象
        Student xiaoming = new Student();
        //2. 利用学生对象打印成员变量的值
        System.out.println("姓名:"+xiaoming.name);    //姓名:null
        System.out.println("年龄:"+xiaoming.age);     //年龄:0
        //3. 利用学生对象对成员变量进行赋值操作
        xiaoming.name = "小明";
        xiaoming.age = 18;
        System.out.println("姓名:"+xiaoming.name);    //姓名:小明
        System.out.println("年龄:"+xiaoming.age);     //年龄:18
        //打印学生对象
        /*
        打印学生对象方式 ---> Task.Student@1218025c --> 理解为学生对象地址【在堆中地址】
        Task---->包名
        Student ---> 证明xiaoming这个对象时属于Student类的
        @ ---> 没有任何意义就是一个连接符号
        1218025c ---> 学生对象记录的堆中开辟空间地址
        */
        System.out.println("学生对象:"+xiaoming);   //学生对象:Task.Student@1218025c
    }
}


图像展示
单个对象在内存中储存

image.png

总结:
  • 只要是创建对象【使用new关键字】,就会在堆中开辟一段空间
  • 只要调用方法,就会在栈中开辟一段空间,用来执行该方法
  • 栈中空间是系统回收操作,堆中空间是Java提供GC【垃圾回收机制】进行回收操作
  • 多个对象在内存中存储
2 多个对象在内存中存储
代码示例
public class StudentTest2 {
    public static void main(String[] args) {
        //1. 创建Student类的对象
        Student xiaoming = new Student();
        //2. 利用学生对象打印成员变量的值
        System.out.println("姓名:"+xiaoming.name);
        System.out.println("年龄:"+xiaoming.age);
        //3. 利用学生对象对成员变量进行赋值操作
        xiaoming.name = "小明";
        xiaoming.age = 18;
        System.out.println("姓名:"+xiaoming.name);
        System.out.println("年龄:"+xiaoming.age);
        System.out.println("学生对象:"+xiaoming);   //学生对象:Task.Student@816f27d
        xiaoming.study();       //正在努力的学习Java......
        //在利用Student类创建一个xiaohong对象,并访问成员变量
        Student xiaohong = new Student();
        System.out.println("姓名:"+xiaohong.name);    //姓名:null
        System.out.println("年龄:"+xiaohong.age);     //年龄:0
    }
}

图像展示
多个对象在内存中存储

image.png

总结:
  • 一个类是可以创建多个对象的,多个对象在堆中存储,都有不同内存划分【就是多个对象都使用new关键字创建】,成员变量是存储在各自的内存区域中,成员方法是多个对象共一份【类文件只有一个】
  • 凡是使用new关键字创建的对象都会在堆中开辟一段新的存储空间
  • 对象和对象之的关系是相互独立的【只要是使用new关键字创建出来】
3 多个对象指向同一个对象在内存那种存储
代码示例
package Task;
public class StudentTest3 {
    public static void main(String[] args) {
        //1. 创建Student类的对象
        Student xiaoming = new Student();
        //2. 利用学生对象打印成员变量的值
        System.out.println("姓名:"+xiaoming.name);
        System.out.println("年龄:"+xiaoming.age);
        //3. 利用学生对象对成员变量进行赋值操作
        xiaoming.name = "小明";
        xiaoming.age = 18;
        System.out.println("姓名:"+xiaoming.name);
        System.out.println("年龄:"+xiaoming.age);
        System.out.println("学生对象:"+xiaoming);   //学生对象:Task.Student@816f27d
        xiaoming.study();       //正在努力的学习Java......
        //在利用Student类创建一个xiaohong对象,并访问成员变量
        //不在使用Student类创建对象,而是使用创建xiaoming对象对另外一个xiaohong对象进行赋值
        Student xiaohong = xiaoming;
        System.out.println("姓名:"+xiaohong.name);  //姓名:小明
        System.out.println("年龄:"+xiaohong.age);  //年龄:18
    }
}


图像展示
多个对象指向同一个对象在内存那种存储

image.png

总结:
  • 当多个对象的引用指向同一个内存空间时【对象所记录地址都是一样的】,只要有任何一个对象修改了内存中数据,随之无论使用哪一个对象进行数据获取,都是修改之后的数据
  • 当创建多个对象时,如果你需要某个对象与另外一个对象的空间是一致,只需要将其中创建好的对象存储空间地址赋值给另外一个对象即可,此时引用就是同一个空间
  • 当创建多个对象时,需要对象彼此之间互相独立不干扰,只需使用new关键字分别创建即可, 就可以在堆中开辟不同存储空间了


目录
相关文章
|
12天前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
28 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
15天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
25天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
141 1
|
18天前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
31 6
|
9天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
31 4
|
12天前
|
存储 Java 开发者
Java 中 Set 类型的使用方法
【10月更文挑战第30天】Java中的`Set`类型提供了丰富的操作方法来处理不重复的元素集合,开发者可以根据具体的需求选择合适的`Set`实现类,并灵活运用各种方法来实现对集合的操作和处理。
|
22天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
43 17
|
12天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
29 2
|
14天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
35 2