【问题标题】:SystemVerilog: Are dynamic arrays (inside classes) guaranteed to be garbage-collected once the class-object is not referenced anymore?SystemVerilog:一旦不再引用类对象,是否保证动态数组(类内部)被垃圾收集?
【发布时间】:2020-07-23 23:05:16
【问题描述】:

所以我的问题是:“标题”以及 SystemVerilog 中动态数组的垃圾收集规则是什么?

上下文:

在我的程序中,我发现了一个错误,您可以在函数中(本地)实例化一个动态数组并在该函数内向该数组添加元素,但如果您不删除该数组,则条目仍保留在那里(即内存和参考被保留)。因此,当您再次调用该函数时,可以访问之前输入的所有条目。解决方案是在退出函数之前简单地删除动态数组。我假设数组没有被删除,因为数组是在堆而不是堆栈上实例化的,并且编译器不知道何时垃圾收集它,因为它可能是返回的引用(如果我错了,请纠正我 -我对动态数组的垃圾回收规则不熟悉)。

但是,如果动态数组在类中实例化(作为成员变量)会发生什么?你怎么知道动态数组是否被删除(即引用和内存被删除)?这种情况下的垃圾回收规则是什么?

如果有帮助,我有示例代码来演示该问题,但我认为没有必要包含它(如果您需要示例,请告诉我)。 附:关联数组也会发生同样的事情(因为我认为它是 SystemVerilog 中动态数组类型的一种形式)。

谢谢!

【问题讨论】:

  • 您在现实中看到的错误很可能是静态变量的正常行为。因此,在这种情况下需要一个示例。如果一个类包含一个非静态数组成员,那么一旦该类被垃圾回收并且当且仅当该数组没有在其他任何地方引用时,它的内存就应该被回收。如果您在那里发现问题,则必须与工具提供商联系。

标签: arrays garbage-collection associative-array system-verilog dynamic-arrays


【解决方案1】:

SystemVerilog 具有三种不同的变量生命周期:

  • 静态——在模拟的整个生命周期中都存在。在时间 0 初始化一次。可以从声明的范围之外引用
  • 自动 -- 为声明它的范围(必须是过程范围)的每个条目创建和初始化一个新实例。它的生命周期在退出作用域时结束,所有嵌套作用域都退出(处理fork/join_none)只能从它被声明的作用域内引用
  • dynamic -- 由执行程序语句创建。它的生命周期可以通过多种方式结束,但通常通过执行程序语句来结束。

动态大小的数组具有生命周期的复合概念。单个元素具有动态生命周期,但数组作为一个整体聚合可以具有上述任何生命周期。出于您的问题的目的,我认为我们可以将数组视为一个聚合。这意味着每当数组变量的生命周期结束时,所有动态分配的元素都会被回收

类对象具有动态生命周期,但持有引用类对象句柄的类变量可以是上述任何生命周期。但是由于不止一个类变量可以引用同一个类对象,当没有更多类变量引用该对象时,类对象的生命周期就结束了。因此,如果该类对象包含动态数组变量,则这些变量的生命周期将在对象生命周期结束时结束。

SystemVerilog 没有指定垃圾收集的工作方式。当某物的生命周期结束时,您将无法再访问它。无法知道内存何时真正被回收。

您的问题似乎是在函数内部有一个静态声明的动态数组,或者是一个静态函数参数。在 Verilog 中,所有非类函数默认都有静态生命周期。类方法只能具有自动生命周期。如果这个解释不能回答你的问题,你需要发布一些代码。


顺便说一句,这成了我DVCon 2021 Paper and Presentation的主题

【讨论】:

  • 好的,这是有道理的。所以我认为系统verilog有像'static'和'automatic'这样的关键字来控制变量生命周期的这个属性。这是正确的吗?
  • 感谢 Dave,看来 systemverilog 的细微差别比我最初想象的要多。
  • 我可以登录验证学院,但仍然看不到论文。是特殊权限吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
  • 2016-02-29
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多