JAVA面试题分享一百三十六:数组为什么是一块连续的空间?

目录

一、什么是数组

二、连续分配管理方式

三、内存紧缩(内存碎片化处理)

四、外部碎片和内部碎片的区别

五、连续存储主要有原因


一、什么是数组

数组

数组是一组在内存中连续存储多个相同类型元素并且有序的数据结构,在内存中的分配也是连续的,一旦初始化完成,长度不可变。
数组本身是引用类型数据,但是可以存储任意类型的数据,包括基本数据类型和引用数据类型,初始化的时候在内存中开辟一块连续的存储空间,数组名指向了该连续空间的首地址。

数组特点

优点

创建数组对象会在内存中开辟一块连续的内存空间,存取有序,通过索引(角标、下标)访问数组中的元素
1、按照索引查询元素速度快
2、按照索引遍历数组方便
缺点
1、数组的长度初始化(数组创建)之后就长度固定不变,无法扩容
2、数组只能存储同一种类型的数据
3、添加,删除的操作慢,因为要移动其他的元素。
数组的增删效率相对较低,因为增删时,是先创建一个新的数组,新数组的长度为旧数组的长度加上或者减去所要增删元素的个数,然后在把增删后的旧数组放到新数组中
适用场景:
频繁查询,对存储空间要求不大,很少增加和删除的情况。

二、连续分配管理方式

1.单一连续存储管理

在这种管理方式中,内存被分为两个区域:系统区和用户区。应用程序装入到用户区,可使用用户区全部空间。

  • 优点:易于管理
  • 缺点:对要求内存空间少的程序,造成内存浪费;程序全部装入,使得很少使用的程序也会占用—定数量的内存。

2.分区式存储管理

分区式存储管理是把内存分为一些大小相等或不等的分区,操作系统占用其中一个分区,其余的分区由应用程序使用,每个应用程序占用一个或几个分区。

3.固定分区

将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业,容易产生浪费和不足。

  • 优点:易于实现,开销小。
  • 缺点:会产生内部碎片,造成浪费;分区总数固定,限制了并发执行的程序数目。

4.动态分区

不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。下面列出了几种常用的分区分配算法:

  1. 最先适配法(nrst-fit):按分区在内存的先后次序从头查找,找到符合要求的第一个分区进行分配。较大的空闲分区可以被保留在内存高端。
  2. 下次适配法(循环首次适应算法 next fit):按分区在内存的先后次序,从上次分配的分区起查找(到最后{区时再从头开始},找到符合要求的第一个分区进行分配。较大空闲分区不易保留。
  3. 最佳适配法(best fit):按分区在内存的先后次序从头查找,找到其大小与要求相差最小的空闲分区进行分配。较大的空闲分区可以被保留。
  4. 最坏适配法(worst fit):按分区在内存的先后次序从头查找,找到最大的空闲分区进行分配。较大空闲分区不易保留。
优点:没有内碎片。
缺点:引入了外部碎片;算法复杂,系统开销大。

三、内存紧缩(内存碎片化处理)

将各个占用分区向内存一端移动,然后将各个空闲分区合并成为一个空闲分区。这种技术在提供了某种程度上的灵活性的同时,也存在着一些弊端,例如:对占用分区进行内存数据搬移占用CPU时间;如果对占用分区中的程序进行“浮动”,则其重定位需要硬件支持。

紧缩时机:每个分区释放后,或内存分配找不到满足条件的空闲分区时。

1、覆盖技术

按自身逻辑把程序分成几个功能上相对独立的模块,不会同时执行的模块可以共享同一块内存区域,按时间先后运行(分时)。

必要的代码和数据常驻内存,不常用的代码在其余模块中实现,并且放在外存,需要时放内存,不存在调用关系的模块不必同时载入内存,可以相互覆盖,共用一个分区。

缺点:设计开销大,程序员要划分模块和确定覆盖关系,编程复杂度增加了;覆盖模块从外存装入内存,实际是以时间来换空间。

2、交换技术

将暂时不能运行的程序送到外存以获得空闲内存空间,操作系统在内存管理单元MMU的帮助下把一个进程的整个地址空间的内容保存到外存中(换出swap out),而将外存中的某个进程的地址空间读入到内存中(换入swap in)。其大小为整个程序的地址空间(比较大,几十几百个页)。

进程再次换入后的内存地址不一定在原来位置上,可能已被占用,因此需要动态地址映射。也就是说同一个进程在两次换入后,虚拟地址一样,物理地址不一样。

3、覆盖与交换的比较

覆盖技术和交换技术的目的是一样的。覆盖是发生在一个运行中的程序内部没有调用关系的模块之间,代价是程序员手动指定和划分逻辑覆盖结构;交换是内存中程序与管理程序或OS之间发生的,以进程作为交换的单位,需要把进程的整个地址空间都换进换出,对程序员是透明的,开销相对较大。

四、外部碎片和内部碎片的区别

1、内部碎片

内部碎片:内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;内存的连续分配方式中的固定分区方法会产生内部碎片。

2、外部碎片

外部碎片:外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。内存的连续分配方式中的动态分区方法会产生内部碎片。

五、连续存储主要有原因

数组在内存中的连续存储主要有以下几个原因:

  1. 访问效率:连续的内存空间可以使得访问数组中的元素更加高效。由于数组元素在内存中是连续的,计算机可以通过计算首元素的内存地址和偏移量来直接访问任意位置的元素,这样的访问时间复杂度是O(1)。
  2. 索引操作:数组使用索引来标识和访问其元素。数组的索引通常是从0开始的整数,表示元素在数组中的位置。由于数组元素在内存中是连续存储的,因此可以通过简单的加法计算来找到任意元素的内存地址,即:元素地址 = 数组首地址 + 索引 * 元素大小。
  3. 内存管理:在操作系统和编程语言中,内存通常被划分为固定大小的块或页面。当为数组分配内存时,系统通常会尝试找到一块连续可用的内存空间来满足请求。如果找到了足够大的连续空间,系统就会将其分配给数组,这使得数组的存储空间在物理内存中是连续的。
  4. 数据结构特性:数组是一种静态数据结构,其大小在创建时确定,并且在整个生命周期内保持不变。这种特性使得数组可以在内存中占据一块连续的空间,因为它们在创建时已经知道了所需的空间大小。相比之下,动态数据结构(如链表)的元素可以任意添加和删除,因此在内存中可能不是连续存储的。
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值