指针碰撞和空闲列表

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump thePointer)。如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(FreeList)。选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。因此,在使用Serial、ParNew等带Compact过程的收集器时,系统采用的分配算法是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,通常采用空闲列表。

下面两张图可以解释指针碰撞和空闲列表:

指针碰撞:

 空闲列表:

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 指针碰撞空闲列表是内存管理中常用的两种分配和释放内存的方式。 指针碰撞是指将可用内存分为两个部分,一部分为已分配内存,一部分为未分配内存。在指针碰撞中,一个指针记录了可用内存的起始地址,当需要分配内存时,指针将会向高地址移动分配的内存大小。当需要释放内存时,指针会向低地址移动释放的内存大小。指针碰撞适用于连续分配内存的情况,如堆内存。 空闲列表是指记录了所有可用内存块的链表。在空闲列表中,每个节点记录了一块可用内存的起始地址和大小。当需要分配内存时,可以遍历空闲列表找到合适大小的内存块并将其分配出去。当需要释放内存时,可以将释放的内存块插入到空闲列表中,合并相邻的空闲块以尽量减小内存碎片。空闲列表适用于随机分配内存的情况,如栈内存。 无论是指针碰撞还是空闲列表,都需要考虑内存碎片的问题。内存碎片是指内存被分成了多个小块,这些小块无法被合并使用,从而导致内存浪费。因此,内存管理中通常需要采取措施来尽量避免内存碎片的产生。 ### 回答2: 指针碰撞空闲列表是两种常见的内存管理算法,在动态内存分配过程中起到了重要作用。 指针碰撞是一种简单且高效的内存分配方式,适用于连续且固定大小的内存块。该算法借助一个指针标记空闲内存的起始地址,并通过移动该指针来确定分配或释放内存的位置。当程序申请内存时,指针向后移动固定的字节数,表示已分配内存的终止位置,并返回当前指针的位置;当释放内存时,只需要将指针移动回到初始位置即可。指针碰撞在内存分配和回收的过程中避免了内存碎片的产生,但要求内存必须是连续的。 空闲列表是另一种内存分配策略,适用于不固定大小的内存块。它基于维护一个记录内存块空闲与占用情况的链表。链表中每个节点包含了一个内存块的起始地址和大小。当申请内存时,空闲列表会轮询链表,找到第一个大小能够满足需求的空闲内存块,并将该块标记为已占用,并返回其起始地址;当释放内存时,会根据释放的内存块的起始地址和大小,将其插入链表中合适的位置,合并相邻的空闲内存块。空闲列表允许不连续的内存分配,但可能会产生内存碎片。 综上所述,指针碰撞适用于固定大小的连续内存分配,通过简单地移动指针来管理内存的分配和回收;而空闲列表适用于不固定大小的不连续内存分配,通过维护一个记录内存空闲与占用情况的链表来管理内存。在实际应用中,需要根据实际需求选择适合的内存管理算法。 ### 回答3: 指针碰撞空闲列表是用于管理内存分配和释放的两种常见算法。 指针碰撞是一种简单的内存管理算法,它基于假设内存是连续可用的,分配和释放内存只需要一个指针即可。当系统需要分配一块内存时,就将指针指向可用内存的开始位置,并将指针向前移动分配的内存大小。当释放内存时,只需要将指针向后移动释放的内存大小即可。指针碰撞适用于固定大小的内存分配,但容易在多线程环境中产生竞争条件。 空闲列表是一种复杂的内存管理算法,它维护了一个记录可用内存块的列表。当系统需要分配内存时,会遍历空闲列表,找到足够大的内存块,然后将该块分配出去。当释放内存时,会将释放的内存块加入到空闲列表中,并尝试合并相邻的空闲块。空闲列表适用于不同大小的内存分配,但需要额外的数据结构来维护空闲块的信息,增加了内存开销和复杂度。 指针碰撞空闲列表都有各自的优缺点。指针碰撞简单高效,适用于固定大小的内存分配,但不适合并发环境。空闲列表适用于动态大小的内存分配,但需要额外的开销和复杂度。在实际应用中,可以根据具体的场景选择更合适的内存管理算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值