是否可以无限的间接引用?

  在翻看《操作系统概念》一书时,在第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系统所使用的指令集是否有书中所提到的最大引用层级限制?

 

如有错误请各位大佬指正,感谢观看

posted @ 2021-06-25 10:32  Cgj20060102030405  阅读(62)  评论(0)    收藏  举报