C语言解释器Java版-0-内存模型

前提说明

由于工作原因,需要实现一个Java版的C语言解释器。在实现的过程中,遇到了很多问题、学到了很多东西,特将实现过程记录下来,备忘的同时,也供后来人学习参考。

在实现之前,已有的内容包括:前端AST、符号表系统和控制流程图。已有的内容我在后文的描述中不会过多说明,所以,看完本系列文章也无法保证读者一定能够按照步骤实现一个Java版的C语言解释器。但是对于一个想要了解解释器或编译器的朋友来说,本系列文章或多或少还是有所帮助的。

Outline

本文主要讲解C语言解释器的内存模型。

0 内存模型

标准内存模型结构如下图所示:
C语言内存模型结构
内存地址从低到高依次分为 代码段区(text)、数据区(data)、堆区(heap)和栈区(stack)。其中,代码段区、数据区是程序实际执行前就确定大小的,堆区和栈区在程序执行过程中动态变化。
在我们的实现中,对每一个区都有大小限制,可能和标准的定义不太相同。每个区可以没有明确的定义界限,根据实际的大小也确定;也可以定义明确的区段界限。也即,内存地址区段的划分只是为了便于识别、记忆、学习或者读取、判断,并不一定是一成不变的。如果需要获取标准的定义,可以去查阅相关官方的文档和资料。

0.1 代码段区

代码段区用于存放要执行函数的二进制代码。内存地址从低向高进行分配。
因为我们已经有前端AST和控制流程图,为了做基于源码的解释执行,在代码段区,我们并没有放入函数的二进制代码,只是放入了函数的入口地址(在后面内存分配会详细说明)。

0.2 数据区

在标准的数据区模型中,数据区可以分为:

  • 常量区,常量区用于存放常量值;
  • 未初始化区(.bss),存放了未初始化的全局变量和静态变量;
  • 初始化区(.data),存放初始化过的全局变量和静态变量。

其中,静态变量包括全局和局部静态变量。这些数据的释放在程序执行结束以后。内存地址从低向高进行分配。
在我们的实现中,初始化区和非初始化的区别意义并不大,所以合并了这两个区(C++内存模型也如做了合并),即数据区由常量区和非常量区构成。在常量区中,主要存放的内容是字符串的常量值。

0.3 堆区

堆区主要用于存放程序执行过程中,由动态内存分配函数分配的内容空间。分配(alloc)和释放(free)都由程序本身来完成。如果在程序中分配了没有释放空间,会导致内存泄露。内存地址从低向高进行分配。
而在Java的内存模型中,堆区的内存由GC进行管理,所以Java不需要程序员手动的调用释放内存的方法。

0.4 栈区

栈区用于存放局部非静态变量(静态变量存放在数据区)。当进入一个函数时,分配所有内存到栈区,函数退出时,释放该函数的所有内存。需要知道的是,栈区的内存分配是从高地址向低地址进行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值