对象创建和内存分配

news2024/11/24 6:34:58

对象创建和内存分配

Java中类创建是在平常不过的操作了,但是一个类的创建到底经历 了哪些过程呢?

对象创建

创建方法

  1. 使用关键字new一个对象

  2. 使用反射机制

    User user = (User)Class.forName("xxx.xxx.User").newInstance(); 
    User user = User.class.newInstance();
    
  3. 使用clone方法

  4. 反序列化

创建过程

在Java中,对象的创建是通过关键字new来实现的。

User user = new User();

JVM在执行以下步骤来创建一个对象:

在这里插入图片描述

  1. 类加载:将Java类的字节码从外部存储到内存中,并在JVM中创建对应的class对象。
  2. 分配内存:JVM会对对象分配内存。
  3. 初始化:一旦对象内存分配完成,JVM将调用丢向的构造器来执行对象的初始化。
  4. 设置对象头:初始化对象后,JVM要对对象进行必要的设置,例如元数据谢谢,哈希码,分代年龄等信息。
  5. init方法:按照程序进行初始化,及对对象赋值,与上面第三步初始化(零赋值)是不同的。

内存分配

分配策略

首先,提出一个这样的问题;

Java中new一个对象,存在哪里?对象的引用存在哪里?static修饰的对象存在哪里?

堆内存: 大多数Java对象都存储在堆内存中。堆内存是JVM的主要内存池,用于存储对象的实例数据。对象在堆上分配,而堆的管理是由垃圾回收器负责的。当对象不再被引用时,垃圾回收器会自动回收堆内存中的对象。

栈内存: 栈内存用于存储局部变量和方法调用信息。基本数据类型和对象引用通常存储在栈上。栈内存的分配和释放非常快速,因为它们仅在方法的生命周期内存在。

方法区: 方法区用于存储类的元数据、静态字段和方法。它也包含字符串常量池和运行时常量池。方法区的内存分配由JVM控制,并在类加载和卸载时发挥重要作用。

分配方法

  • 指针碰撞

    当分配新对象的时候,JVM会维护一个指针,指向下一个可用的内存位置,分配新对象时,JVM将指针向前移动,以便在堆上分配新对象的内存空间。

  • 空闲列表

    通过维护一个空闲列表,当需要分配新对象时,JVM会在空闲列表中寻找一个合适的内存块,将其分配给新对象。然后更新空闲列表。

分配过程

首先,提出一个问题?

什么情况下,对象会分配到栈内存上?

在这里插入图片描述

现在来回答上面问题,对象一般是在堆上进行分配的,但是JVM为了减少对象在堆上分配的数量,JVM进行逃逸分析确认该对象会不会对外部访问,如果不会则将该对象分配到栈内存上面去。出栈的时候将该对象销毁,减轻垃圾回收的负担。

对象逃逸分析

对象逃逸分析是一种用于对象在其生命周期中是否逃逸出方法的作用域的优化技术。当对象没有逃逸时,则分配在堆上;对象逃逸了,则直接分配到栈上,减少堆对象的数量以及垃圾回收负担。

举个例子:

 	public void createObject() {
        // 在方法内部创建一个对象,并将其赋值给成员变量
        obj = new Object();
    }

    public Object getObject() {
        // 返回对象的引用
        return obj;
    }

上面代码中,createObject()会出现对象逃逸,getObject()没有出现对象逃逸。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1015521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux开发工具之编译器gcc/g++

gcc/g是编译代码的,gcc/g都可以编译c语言的代码,但是c的代码只能用g来编译 在linux中,只要我们对源文件用gcc/g进行编译,就会生成一个可执行程序a.out,然后我们执行该程序就可得到结果了,下面来细看一下gcc…

深入了解==和equals的区别

1. 浅说和equals的区别 (1)比较的类型 不一样 可以比较基础数据类型和引用类型,比较基础数据类型的数据时比较的是值,比较引用对象时比较的是引用的地址。 equals比较引用类型,默认比较的是两个引用对象的引用地址&a…

Acwing 3302. 表达式求值

Acwing 3302. 表达式求值 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 #include <iostream> #include <cstring> #include <algorithm> #include <stack> #include <unordered_map>using namespace std;stack<int> num; stack…

redis链接阻塞,导致程序没有响应

目录 一、场景二、原因三、排查1、使用 info client 命令查看redis链接统计情况2、使用 client list 命令查看redis链接信息3、关闭程序&#xff0c;看阻塞的链接是否有所减少4、排查使用 blpop 命令的相关代码 四、解决 一、场景 1、程序在运行一段时间后&#xff0c;会出现没…

【分布式】分布式ID

目录 前言一、雪花算法snowflake1. 组成2. 优缺点3. 时钟回拨怎么解决a. 时钟回拨b. 解决方案 4. 项目中如何使用 二、基于Redis三、基于Zookeeper四、号段模式五、指定步长的自增ID六、UUID参考 六、扩展总结 前言 分布式场景下&#xff0c;一张表可能分散到多个数据结点上。因…

【数据结构】C++实现二叉搜索树

二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于根结点的值。若它的右子树不为空&#xff0c;则右子树上所有结点的值都大于根结…

问道管理:注册制对涨幅的限制?

注册制作为中国证券商场变革的重中之重&#xff0c;其本质是将发行商场转移到审阅商场&#xff0c;实现商场准入的有效管控。与此同时&#xff0c;注册制关于股票商场的涨幅也有必定的约束。 首先&#xff0c;注册制能够经过严厉的审阅来制约公司发行股票的数量和节奏。传统IP…

Linux 多线程( 进程VS线程 | 线程控制 )

文章目录 Linux进程 VS 线程进程的多个线程共享 进程和线程的关系线程创建 pthread_create获取线程ID pthread_self线程等待 pthread_join终止线程进程分离线程ID及进程地址空间布局 Linux进程 VS 线程 进程是资源分配的基本单位。线程是OS调度的基本单位。 线程共享进程数据…

Michael.W基于Foundry精读Openzeppelin第34期——MerkleProof.sol

Michael.W基于Foundry精读Openzeppelin第34期——MerkleProof.sol 0. 版本0.1 MerkleProof.sol 1. 目标合约2. 代码精读2.1 processProof(bytes32[] memory proof, bytes32 leaf) && processProofCalldata(bytes32[] calldata proof, bytes32 leaf)2.2 verify(bytes32[…

图像处理之频域滤波DFT

摘要&#xff1a;傅里叶变换可以将任何满足相应数学条件的信号转换为不同系数的简单正弦和余弦函数的和。图像信号也是一种信号&#xff0c;只不过是二维离散信号&#xff0c;通过傅里叶变换对图像进行变换可以图像存空域转换为频域进行更多的处理。本文主要简要描述傅里叶变换…

Heap及其应用

目录 堆的相关知识 什么是堆&#xff1f; 堆的性质&#xff1a; 堆的实现&#xff1a; 堆的结构&#xff1a; &#xff08;一&#xff09;堆的插入 向上调整法&#xff1a; 寻找父节点 循环结束条件 代码&#xff1a; &#xff08;二&#xff09;堆的删除 删除根节点…

Huggingface:免费开源AI人工智能API工具平台

| 【产品介绍】 • 名称 Huggingface • 成立/上线时间 2016年 • 具体描述 HuggingFace是一个开源的自然语言处理AI工具平台&#xff0c;它为NLP的开发者和研究者提供了一个简单、快速、高效、可靠的解决方案&#xff0c;让NLP变得更加简…

R绘制箱线图

代码大部分来自boxplot()函数的帮助文件&#xff0c;可以通过阅读帮助文件&#xff0c;调整代码中相应参数看下效果&#xff0c;进而可以理解相应的作用&#xff0c;帮助快速掌握barplot()函数的用法。 语法 Usage(来自帮助文件) barplot(height, ...)## Default S3 method: …

lua环境搭建数据类型

lua作为一门计算机语言&#xff0c;从语法角度个人感觉还是挺简洁的接下来我们从0开始学习lua语言。 1.首先我们需要下载lua开发工具包 在这里我们使用的工具是luadist 下载链接为&#xff1a;https://luadist.org/repository/下载后的压缩包解压后就能用。 2.接下来就是老生…

听GPT 讲Istio源代码--istioctl

在 Istio 项目的 istioctl 目录中&#xff0c;有一些子目录&#xff0c;每个目录都有不同的作用和功能。以下是这些子目录的详细介绍&#xff1a; /pkg: pkg 目录包含了 istioctl 工具的核心代码和库。这些代码和库提供了与 Istio 控制平面交互的功能&#xff0c;例如获取和修改…

postgresql 内核源码分析 btree索引插入分析,索引页面分裂流程,多举措进行并发优化,对异常进行保护处理

Btree索引插入流程分析 ​专栏内容&#xff1a; postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献&#xff1a; toadb开源库 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&a…

Swing程序设计详解(一)

【今日】 “若你决定灿烂&#xff0c;山无遮&#xff0c;海无拦” 目录 初识Swing 一 Swing简述 二 Swing常用窗体 2.1 JFrame窗体 2.2 JDialog对话框 2.3JOptionPane小型对话框 (1)通知框 (2)确认框 (3)输入框 (4)自定义对话框 三 常用布局管理器 3.1 绝…

JWT生成与解析/JWT令牌前端存储

第一步&#xff1a;创建项目 添加Maven依赖&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version> </dependency> <dependency><groupId>org.s…

【C++】深拷贝和浅拷贝 ② ( 默认拷贝构造函数是浅拷贝 | 代码示例 - 浅拷贝造成的问题 )

文章目录 一、默认拷贝构造函数是浅拷贝1、默认拷贝构造函数2、默认拷贝构造函数是浅拷贝机制 二、代码示例 - 浅拷贝造成的问题 一、默认拷贝构造函数是浅拷贝 1、默认拷贝构造函数 如果 C 类中 没有定义拷贝构造函数 , C 编译器会自动为该类提供一个 " 默认的拷贝构造函…

GeoJSON转STL:地形3D打印

我们通过将 GeoJSON 形状坐标提取到点云中并使用 Open3d 应用泊松重建&#xff0c;从 GeoJSON 数据重建 STL 网格。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 我对打印 GeoJSON 山丘的第一次尝试深感不满&#xff0c;因此想出了一个三步流程&#xff0c;仅使用开源…