是否可以无限的间接引用?
在翻看《操作系统概念》一书时,在第9章关于内存帧分配的描述中,一个进程的内存帧最小数量由指令的操作数引用的内存所决定。例如IBM 370 MVC指令将一个内存地址的值移动到另一个内存地址,这时如果两个内存地址对应不同两个物理内存帧,那么就最小帧数量就为2。那么这里面存在一些比较特殊的情况:如果MVC的第一个操作数是一个内存引用(指针),而指针所指向的原地址可能也是一个指针(多层间接引用),而储存这些指针的物理内存帧可能是不同,那么这条MVC指令的最小内存帧是多少呢?书中也列出了这种最坏情况,并且提出必须给间接引用增加一个限制,以保证多任务系统的内存使用效率和页置换时的性能。下图为书中原文:
从而引出了标题的问题,在各大网站上都没有搜索到想要的答案,所以想自己验证一下,我们以golang为例,在golang中可以无限层的间接引用吗?
探索一:
书中写到:例如,限制一个指令只能有16级的间接引用。那么我们首先试一下16级间接引用是否可行,傻写了一段代码:
import ( "fmt" )
func main() { var ans int ans = 10 ansp1 := &ans ansp2 := &ansp1 ansp3 := &ansp2 ansp4 := &ansp3 ansp5 := &ansp4 ansp6 := &ansp5 ansp7 := &ansp6 ansp8 := &ansp7 ansp9 := &ansp8 ansp10 := &ansp9 ansp11 := &ansp10 ansp12 := &ansp11 ansp13 := &ansp12 ansp14 := &ansp13 ansp15 := &ansp14 ansp16 := &ansp15 ansp17 := &ansp16 fmt.Println(*****************ansp17, ans) return }
// output
// 10, 10
没有任何问题,输出正常。看来连续取地址17次是没有问题的,继续探索。
探索二:
写一个循环,达到n次间接引用
import ( "fmt" ) func main() { var original, n int var p interface{} original = 100 n = 10000 p = &original
// n次取址 for i := 0; i < n; i++ { tmp := p p = &tmp fmt.Println(tmp, p) } fmt.Println("--------------")
// n次回溯拿到原值 for i := 0; i < n; i++ { tmp := p.(*interface{}) p = *tmp fmt.Println(tmp, *tmp) } res := p.(*int) fmt.Println("original:", original, "result:", *res) }
// original: 100 result: 100
同样没有问题,输出结果与预期相符。可以得出结论:golang中是可以无限的间接引用的。再仔细看书发现可能是对cpu的指令是有限制的,在高级编程语言层面并没有这样的限制
疑惑:
1. 可以无限的间接引用代表可以无限取址吗?例如“探索一”中的代码无限写下去?
2. 我们常用的linux/unix系统所使用的指令集是否有书中所提到的最大引用层级限制?
如有错误请各位大佬指正,感谢观看