gpt4 book ai didi

memory-management - 在某些情况下,Ada 会自动释放内存吗?

转载 作者:行者123 更新时间:2023-12-03 18:43:03 25 4
gpt4 key购买 nike

我试图找到一些关于为什么关键字 new 可用于动态分配对象但没有像 delete 这样的关键字可用于释放它们的信息。通过在 Ada 2012 引用手册中提到的 Ada.Unchecked_Deallocation,我发现了一些有趣的摘录:

Every object is finalized before being destroyed (for example, byleaving a subprogram_body containing an object_declaration, or by a call to an instance ofUnchecked_Deallocation)


Each access-to-object type has an associated storage pool. The storage allocated by an allocator comesfrom the pool; instances of Unchecked_Deallocation return storage to the pool.


The Deallocate procedure of a user-defined storage pool object P may be called by the implementation todeallocate storage for a type T whose pool is P only at the places when an Allocate call is allowed for P,during the execution of an instance of Unchecked_Deallocation for T, or as part of the finalization of thecollection of T.


如果我不得不猜测,这意味着当执行离开声明访问的范围时,实现有可能自动释放与访问关联的对象。无需显式调用 Unchecked_Deallocation
这似乎得到 a section in Ada 95 Quality and Style Guide 的支持,其中指出:

The unchecked storage deallocation mechanism is one method for overriding the default time at which allocated storage is reclaimed. The earliest default time is when an object is no longer accessible, for example, when control leaves the scope where an access type was declared (the exact point after this time is implementation-dependent). Any unchecked deallocation of storage performed prior to this may result in an erroneous Ada program if an attempt is made to access the object.


但措辞相当不明确。如果我运行这段代码,内存方面到底会发生什么?
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
procedure Run is
X : access Integer := new Integer'(64);
begin
Put (Integer'Image (X.all));
end Run;
begin
for I in 1 .. 16 loop
Run;
end loop;
end Main;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
procedure Outer is
type Integer_Access is not null access Integer;
procedure Run is
Y : Integer_Access := new Integer'(64);
begin
Put (Integer'Image (Y.all));
end Run;
begin
for I in 1 .. 16 loop
Run;
end loop;
end Outer;
begin
Outer;
end Main;
X 完成时是否有保证的内存泄漏或 Run 被释放?

最佳答案

Memory Management with Ada 2012 中所述,引用 here ,局部变量通常分配在堆栈上;当变量的作用域退出时,它的内存会自动释放。相比之下,动态变量通常分配在堆上;它的内存是使用 new 分配的,它的内存必须被回收,通常:

  • 明确地,例如使用 Unchecked_Deallocation 的一个实例。
  • 隐式,例如使用派生自 Finalization 的受控类型;如上所述 here ,当受控实例的范围退出时,自动终结调用 Finalize ,它以适合类型设计的方式回收存储。
  • Ada.Containers 的子代在内部使用受控类型来封装访问值并自动管理内存。作为引用,将特定容器的编译器实现与 here 引用的相应功能容器进行比较。
    Ada 提供了多种管理内存的方法,在幻灯片 28 上按照作者的偏好顺序进行了总结:
  • 基于堆栈。
  • 基于容器。
  • 基于定稿。
  • 基于子池。
  • 手动分配/解除分配。

  • Main 的特殊情况下,程序为 Integer 的 16 个实例分配存储空间。如幻灯片 12 所述,“当相应的访问类型超出范围时,编译器可能会回收分配的内存。”例如,最近版本的 GNAT 引用手册表明遵循以下存储管理实现建议:

    A storage pool for an anonymous access type should be created at the point of an allocator for the type, and be reclaimed when the designated object becomes inaccessible.


    如果没有这样的指示,则不需要回收存储。它通常在程序退出时由主机操作系统回收。

    关于memory-management - 在某些情况下,Ada 会自动释放内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67131931/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com