Chapter 17_1 弱引用table

本文深入探讨Lua的自动内存管理机制,包括其增量标记-扫描垃圾收集器的工作原理,以及如何通过设置垃圾收集器间歇率和步进倍率来控制垃圾回收过程。此外,文章详细介绍了Lua中的弱引用table概念,包括弱引用key和value的实现方式,以及如何利用元表的__mode字段来创建不同类型的弱引用table。

  Lua采用了自动内存管理。所以不用担心新创建的对象需要的内存如何分配出来,也不用考虑对象不再被使用后怎样释放它们所占用的内存。

Lua实现了一个增量标记-扫描收集器。它使用这两个数字来控制垃圾收集循环:垃圾收集器间歇率 和 垃圾收集器步进倍率。

这两个数字都使用百分数为单位(例如:100在内部表示1)

  前者表示控制收集器需要在开启新的循环前要等待多久,后者表示控制收集器运作速度相对于内存分配速度的倍率(不要设置为小于100,否则收集慢于分配)。

  在Lua中,你可以用弱引用和终结器作为垃圾回收的机制。先来看弱引用table。

  用户能用它来告诉Lua一个引用不应该阻碍一个对象的回收。弱引用就是一种会被垃圾收集器忽视的对象引用

  如果一个对象的所有引用都是弱引用,那么Lua就可以回收这个对象了,并且还可以以某种形式来删除这些弱引用本身。

Lua用 “弱引用table” 来实现 “弱引用”,一个弱引用table就是一个具有弱引用条目的table。

如果一个对象只被一个弱引用table所持有,那么最终Lua会回收这个对象。

通常,垃圾收集器不会回收一个可访问table中的作为key或value的对象。也就是说,这些key和value都是强引用,它们会阻止对其所引用对象的回收。

在一个弱引用table中,key和value是可以回收的。有3种弱引用table:

  1》具有弱引用key的table

  2》具有弱引用value的table

  3》同时具有两种弱引用的table

不管哪种类型的table,当一个key或value被回收,那么它们所在的整个条目都会从table中删除。

  一个table的弱引用类型是通过元表中的__mode字段来决定的。这个字段的值为一个字符串:

  “k” :表示key是弱引用的

  “v":表示value是弱引用的

  “kv”:表示key和value都是弱引用

  下面的代码演示了弱引用table的基本行为:

a = {}
b = {__mode = "k" }
setmetatable(a,b)             -- now 'a' 的key就是弱引用
key = {}                      -- 创建第一个key
a[key] = 1
key = {}                      --创建第二个key,覆盖第一个key(没有了引用,将会被回收)
a[key] = 2                    --引用了变量key
collectgarbage()              --强制进行一次垃圾回收
for k , v in painrs(a) do 
    print(v)                  -- 2
end

Lua只会回收弱引用table中的对象。而像数字和布尔这样的值是不可回收的。

如果一个数字key所对应的value被回收了,那么整个条目都会从这个弱引用table中删除。

字符串在此显得有点特殊:看上去是可回收的,但是在有些方面与其他可回收对象不同。

其他对象,比如table和thread,都是显式创建的。

当Lua对表达式{}求值时,它就会创建一个新的table。同样地,当对“a” .. "b"求值 会创建一个新的字符串吗?

如果当前系统中已有一个字符串"ab",它会复用吗?还是创建一个新的字符串?

这些都无关紧要,它们都是实现的细节。从程序员角度看,字符串就是值,而非对象。

因此,字符串就像数字和布尔一样,不会从弱引用table中删除(除非和它相关联的值被回收)。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

转载于:https://www.cnblogs.com/daiker/p/5884519.html

要解决在 `/home/ls/dev1/chapter3_ws/install/chapter3_tutorials/share/chapter3_tutorials` 包的共享目录中找不到 `example4_5.launch` 文件的问题,可以按以下步骤排查和解决: ### 检查文件是否存在于源码目录 通常,ROS 包在编译后会将 `launch` 文件等资源安装到共享目录。首先需要确认该文件是否存在于源码目录中。一般 `launch` 文件会存放在 `launch` 子目录下,使用以下命令检查: ```bash ls /home/ls/dev1/chapter3_ws/src/chapter3_tutorials/launch ``` 如果文件不存在,可能是没有正确编写或者放置该 `launch` 文件。 ### 检查编译配置 确保 `CMakeLists.txt` 文件中正确配置了 `launch` 文件的安装规则。在 `CMakeLists.txt` 中应该有类似如下的内容: ```cmake install(DIRECTORY launch/ DESTINATION share/${PROJECT_NAME} FILES_MATCHING PATTERN "*.launch" ) ``` 如果没有这部分内容,需要添加进去。 ### 重新编译工作空间 在修改了 `CMakeLists.txt` 后,需要重新编译工作空间,使用以下命令: ```bash cd /home/ls/dev1/chapter3_ws catkin_make ``` 或者使用 `catkin build`(如果使用 `catkin_tools`): ```bash cd /home/ls/dev1/chapter3_ws catkin build ``` ### 检查环境变量 确保 ROS 环境变量正确设置,每次打开新的终端都需要重新加载环境变量: ```bash source /home/ls/dev1/chapter3_ws/devel/setup.bash ``` ### 检查文件权限 确保文件权限允许被复制到共享目录。可以使用以下命令修改文件权限: ```bash chmod +x /home/ls/dev1/chapter3_ws/src/chapter3_tutorials/launch/example4_5.launch ``` ### 检查安装目录 再次确认文件是否已经被正确安装到共享目录: ```bash ls /home/ls/dev1/chapter3_ws/install/chapter3_tutorials/share/chapter3_tutorials ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值