装箱拆箱

简介: 装箱拆箱

装箱和拆箱


什么是装箱和拆箱。它其实很简单,把值类型实例转换为引用类型实例,就是装箱。相反,把引用类型实例转换为值类型实例,就是拆箱。

// 装箱
int a = 5;
object obj = a;
//拆箱
a = (int)obj;

值类型数据会直接存储变量


装箱,因为a 是值类型是直接有数据的变量,obj为引用类型是指针与内存是拆分开来的,把 a 赋值给 b 实际上就是 b 为自己创建了一个指针并指向了a的数据空间。


引用类型的变量会在声明时预留出内存地址,其为null, 当进行new创建实例的时候,就分配了堆上的内存空间,把空间地址保存给这个引用变量。


拆箱,相当于把 obj 指向的内存空间复制一份交给了a,因为 a 是值类型,它不允许指向某个内存空间只能靠复制数据来传递数据。


为何需要装箱


栈是本着先进后出的数据结构(LIFO)原则的存储机制,它是一段连续的内存,所以对栈数据的定位比较快速, 而堆则是随机分配的空间,


处理的数据比较多, 无论如何,


至少要两次定位。堆内存的创建和删除节点的时间复杂度是O(logn)。栈创建和删除的时间复杂度则是O(1),栈速度更快。


那么既然栈速度这么快,全部用栈不就好了。这又涉及到生命周期问题,由于栈中的生命周期是必须确定的,销毁时必须按次序销毁,从最后分配的块部分开始销毁,创建后什么时候销毁必须是一个定量,所以在分配和销毁时不灵活,基本都用于函数调用和递归调用中,这些生命周期比较确定的地方。相反堆内存可以存放生命周期不确定的内存块,满足当需要删除时再删除的需求,所以堆内存相对于全局类型的内存块更适合,分配和销毁更灵活。


当程序、逻辑或接口需要更加通用的时候才会需要装箱。比如调用一个含类型为object的参数的方法,该object可支持任意为型,以便通用。当你需要将一个值类型(如Int32)传入时,就需要装箱。又比如一个非泛型的容器为了保证通用,而将元素类型定义为object,当值类型数据加入容器时需要装箱。


装箱的内部操作


装箱: 根据相应的值类型在堆中分配一个值类型内存块,再将数据拷贝给它。按三步进行。


第一步:在堆内存中新分配一个内存块(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。


第二步:将值类型的实例字段拷贝到新分配的内存块中。


第三步:返回内存堆中新分配对象的地址。这个地址就是一个指向对象的引用了。


拆箱 :更为简单点,先检查对象实例,确保它是给定值类型的一个装箱值,再将该值从实例复制到值类型变量的内存块中。


装箱、拆箱对执行效率有哪些影响,如何优化。


由于装箱、拆箱时生成的是全新的对象,不断得分配和销毁内存会不但大量消耗CPU,也同时增加了内存碎片,降低了性能。 那该如何做呢?


最需要我们做的就是减少装箱、拆箱的操作,在我们编程规范中要牢记这种比较浪费CPU的操作,在平时编程要特别注意。


整数、浮点数、布尔等数值型变量的变化手段很少,变不出什么花样来,主要靠加强规范减少装拆箱的情况来提高性能。Struct 有点不一样,它既是值类型,又可以像类一样继承,用途多转换的途径多可变的花样多,稍不留神花样就变成了麻烦,所以这里讲讲 Struct 变化后的优化方法。


1.Struct 通过重载函数来避免拆箱、装箱。 ToString(), GetType(), 如果 Struct 没有写重载ToString()和GetType()的方法,就会在 Struct 实例调用它们时先装箱再调用,导致内存块重新分配性能损耗,所以对于那些需要调用的引用方法,必须重载。


2.通过泛型来避免拆箱、装箱。 不要忘了 Struct 也是可以继承的,在不同的、相似的、父子关系的 Struct 之间可以用泛型来传递参数,这样就不用装箱后再传递了。


比如B,C继承A,就可以有这个泛型方法 void Test(T t) where T:A,以避免使用object引用类型形式传递参数。


3.通过继承统一的接口提前拆箱、装箱,避免多次重复拆箱、装箱。 很多时候拆装箱不可避免,那么我们就让多种 Struct 继承某个统一的接口,不同的 Struct 就可以有相同的接口。把 Struct 传递到其他方法里去时就相当于提前进行了装箱操作,在方法中得到的是引用类型的值,并且有它需要的接口,避免了在方法中重复多次的拆装箱操作。比如 Struct A 和 Struct B 都继承接口 I,我们调用的方法是 void Test(I i)。当调用Test方法时传进去的 Struct A 或 Struct B 的实例都相当于提前做了装箱操作,Test里拿到的参数后就不用再担心内部再次装箱拆箱问题了。

相关文章
阿里云服务器3年和5年活动价格参考,阿里云服务器3年和5年活动价格整理
目前阿里云各活动中的云服务器默认显示的价格都是1个月或者1年的价格,有的用户以为活动内的云服务器只能买1年,其实不是的,活动内的大部分云服务器都是可以买3年和5年的,可以买3年的云服务器为通用算力型u1云服务器,可买5年的云服务器有计算型c7、通用型g7、内存型r7和计算型c8y、通用型g8y、内存型r8y,现在购买阿里云各活动内的云服务器3年最低价格是2147.76元,5年最低价格是3003.03元,本文为大家介绍下阿里云目前活动内的云服务器如何购买3年和5年,及3年或5年的具体优惠价格。
547 1
阿里云服务器3年和5年活动价格参考,阿里云服务器3年和5年活动价格整理
|
10月前
|
C++
C/C++】如何不使用 sizeof 求数据类型占用的字节数
C/C++】如何不使用 sizeof 求数据类型占用的字节数
Java开发常用工具网址
Java开发常用工具网址
Zp
133 0
从零开始配置MySQL MMM (续)——32bit CentOS 5上遇到的一些问题
在上一篇《从零开始配置MySQL MMM》中,在64bit的RHEL6中安装和配置MySQL-mmm。这两天又拿到了一个全32bit的CentOS 5,在配置过程中有遇到了一些其他问题。 一、依赖问题         因为这个环境中无法通过yum直接安装mysql-mmm,所以只有通过下载安装文件进行安装。
997 0
小鱼深度评测 | 通义灵码2.0,不仅可跨语言编码,自动生成单元测试,更炸裂的是集成DeepSeek模型且免费使用,太炸裂了。
小鱼深度评测 | 通义灵码2.0,不仅可跨语言编码,自动生成单元测试,更炸裂的是集成DeepSeek模型且免费使用,太炸裂了。
141048 20
小鱼深度评测 | 通义灵码2.0,不仅可跨语言编码,自动生成单元测试,更炸裂的是集成DeepSeek模型且免费使用,太炸裂了。
基于阿里百炼的DeepSeek-R1满血版模型调用【零门槛保姆级2084小游戏开发实战】
本文介绍基于阿里百炼的DeepSeek-R1满血版模型调用,提供零门槛保姆级2048小游戏开发实战。文章分为三部分:定位与核心优势、实战部署操作指南、辅助实战开发。通过详细步骤和案例展示,帮助开发者高效利用DeepSeek-R1的强大推理能力,优化游戏逻辑与视觉效果,解决官网响应延迟问题,提升开发效率和用户体验。适合企业开发者、教育行业及多模态探索者使用。
70871 17
基于阿里百炼的DeepSeek-R1满血版模型调用【零门槛保姆级2084小游戏开发实战】
深度评测 | 仅用3分钟,百炼调用满血版 Deepseek-r1 API,百万Token免费用,简直不要太爽。
仅用3分钟,百炼调用满血版Deepseek-r1 API,享受百万免费Token。阿里云提供零门槛、快速部署的解决方案,支持云控制台和Cloud Shell两种方式,操作简便。Deepseek-r1满血版在推理能力上表现出色,尤其擅长数学、代码和自然语言处理任务,使用过程中无卡顿,体验丝滑。结合Chatbox工具,用户可轻松掌控模型,提升工作效率。阿里云大模型服务平台百炼不仅速度快,还确保数据安全,值得信赖。
357994 61
深度评测 | 仅用3分钟,百炼调用满血版 Deepseek-r1 API,百万Token免费用,简直不要太爽。
Manus:或将成为AI Agent领域的标杆
随着人工智能技术的飞速发展,AI Agent(智能体)作为人工智能领域的重要分支,正逐渐从概念走向现实,并在各行各业展现出巨大的应用潜力。在众多AI Agent产品中,Manus以其独特的技术优势和市场表现,有望成为该领域的标杆。作为资深AI工程师,本文将深入探讨Manus的背景知识、主要业务场景、底层原理、功能的优缺点,并尝试使用Java搭建一个属于自己的Manus助手,以期为AI Agent技术的发展和应用提供参考。
10986 12
快速使用 DeepSeek-R1 满血版
DeepSeek是一款基于Transformer架构的先进大语言模型,以其强大的自然语言处理能力和高效的推理速度著称。近年来,DeepSeek不断迭代,从DeepSeek-V2到参数达6710亿的DeepSeek-V3,再到性能比肩GPT-4的DeepSeek-R1,每次都带来重大技术突破。其开源策略降低了AI应用门槛,推动了AI普惠化。通过阿里云百炼调用满血版API,用户可以快速部署DeepSeek,享受高效、低成本的云端服务,最快10分钟完成部署,且提供免费token,极大简化了开发流程。
156956 21
快速使用 DeepSeek-R1 满血版
阿里云百炼已上线超强推理开源模型QwQ-32B,尺寸更小,性能比肩DeepSeek满血版
通义千问团队推出了320亿参数的QwQ-32B模型,通过大规模强化学习和多阶段训练,在数学、编程及通用能力上达到或超越了DeepSeek-R1等先进模型。QwQ-32B模型已在阿里云百炼上线,支持API调用,用户可通过官方文档了解详细使用方法。未来,团队将继续探索智能体与RL集成,推动人工通用智能的发展。