实验 通过命令和代码初步感受存储管理【操作系统】

简介: 实验 通过命令和代码初步感受存储管理【操作系统】

通过命令和代码初步感受存储管理

1.什么是存储器的层次结构,如何通过命令进行查看?

大家所熟知的是内存(RAM)和外存,尽管内存比外存速度快很多,但还是无法与CPU的速度匹配,因此CPU内部就需要更快的存储装置,这就是高速缓存(Cache)。从图中看出,高速缓存并不属于内存,而属于CPU的组成部分。另外,还有内存管理单元MMU(Memory Management Unit),这是为了支持虚拟内存管理而专门设置的硬件机制,也属于CPU的管辖范围。可以看出,为了支持内存管理,CPU使出了浑身解数,CPU和内存的关联更加紧密。

那么如何查看CPU中的Cache ?

我们可以通过lscpu命令查看CPU内部的缓存,




从输出结果看,在x86机器上,
L1d 和L1i cache,为一级数据和指令缓存,大小都为32k,
L2,L3Cache为二级和三级缓存,分别是521K,8192K,大小各不同。

可以通过free命令查看内存的情况。

free命令查看内存
Mem 行(第二行)是内存的使用情况。
Swap 行(第三行)是交换空间的使用情况。
total 列显示系统总的可用物理内存和交换空间大小。
used 列显示已经被使用的物理内存和交换空间。
free 列显示还有多少物理内存和交换空间可用使用。
shared 列显示被共享使用的物理内存大小。
buff/cache 列显示被 buffer 和 cache 使用的物理内存大小。
available 列显示还可以被应用程序使用的物理内存大小。

2. 如何编译、链接、装载并执行一个程序?




3. Linux中进程地址空间是怎样的?


一个程序编译链接后形成可执行文件,可执行文件加载执行后,就摇身一变成为进程了,进程地址空间如图最右边所示。除了代码区,初始化数据区,BSS区外,还有堆、栈和共享库等,其中,栈中存放存放函数的参数值、返回值、局部变量等,而堆是用来为用户程序中的malloc()等分配内存的,printf函数存放在共享库中。

4. 如何编写代码 感受自己写的代码放在进程地址空间的哪些段中?

代码

请敲如下代码:

#include  <stdio.h>
#include  <stdlib.h>
#include  <unistd.h>
int A;        //全局未初始化变量
int B=0;      //全局初始化为0的变量
int C=2;      //全局初始化变量
static int D;     //全局静态未初始化变量
static int E=0;   //全局静态初始化为0的变量
static int F=4;   //全局静态初始化变量
const  int G=5;   //全局常量
const char H=6; 
int main(void){
  int a;       //局部未初始化变量
  int b=0;           //局部初始化为0的变量
  int c=2;           //局部初始化变量
  static  int d;     //局部静态未初始化变量
  static  int e=0;      //局部静态初始化为0的变量
  static int f=4;       //局部静态初始化变量
  const int g=5;        //局部常量
  char  char1[] = "abcde";//局部字符串数组
  char  *cptr="123456";   //p在栈上,123456在常量区
  int *heap=malloc(sizeof(int)*4);//堆
  printf("PID is :%d\n\n",  getpid());
  printf("int A           A_addr = %p\n",&A);
  printf("int B=0         B_addr = %p\n",&B);
  printf("int C=2         C_addr = %p\n",&C);
  printf("static int D        D_addr = %p\n",&D);
  printf("static int E=0      E_addr = %p\n",&E);
  printf("static int F=4      D_addr = %p\n",&F);
  printf("const int G=5      G_addr = %p\n",&G);
  printf("const char H=6      H_addr = %p\n",&H); 
  printf("\n");
  printf("int a           a_addr = %p\n",&a);
  printf("int b=0         b_addr = %p\n",&b);
  printf("int c=2         c_addr = %p\n",&c);
  printf("static int d        d_addr = %p\n",&d);
  printf("static int e=0      e_addr = %p\n",&e);
  printf("static int f=4      f_addr = %p\n",&f);
  printf("const int g=5      g_addr = %p\n",&g);
  printf("\n");
  printf("char char1[] = 'abcde'\t\t\tchar1_addr = %p\n",char1);
  printf("char char1[] = 'abcde'\t\t\t&char1_addr = %p\n",&char1);
  printf("char *cptr  = '1'\t\t\tcptr_addr = %p\n",&cptr);
  printf("value of the cptr\t\t\tcptr_value = 0x%p\n",cptr);
  printf("value of the %p\t\t\tvalue_0x%p = %d\n",cptr,cptr,*cptr);
  printf("int* heap = malloc(sizeof(int)*4)\theap__addr = %p\n",heap);
  printf("int* heap = malloc(sizeof(int)*4)\t&heap__addr = %p\n",&heap);
  pause();
  //程序结束运行之后再回收堆内存,方便观案堆的地址 
  free(heap);
  return 0;
}

编译并运行该程序:


仔细分析你的运行结果,你发现什么?

结果





你也可以用size命令进行查看。

分析

进程地址空间的段说明

在图片下搜索关键词

32位4GLinux虚拟地址空间布局






【Linux】Linux下4G虚拟地址空间布局

简述代码中关于.data、.bss、.rodata、.text段的意义

kernel space 内核空间

Undefined Region

Stack

Memmory Mapping Region 共享库
heap

bss段(Block(b) Started(s) by Symbol(s)):即用来存储一些未被初始化的全局变量和静态变量的内存区域,一般在初始化时bss段部分将会清零,属于静态内存分配,即程序一开始就将其清零了。

例:



#include<xxx.h>
int bss_value1;//全局的未被初始化的变量,处于bss段
static void *bss_value2 = NULL;//全局的指针变量,处于bss段
int main()
{
//…;
return 0;
}

注意:BSS段不包含任何数据,只是简单的维护开始和结束的地址,以便内存区能在运行时被有效的清零。并不给该段的数据分配空间,只是记录数据所需空间的大小。不占用可执行文件的空间,BSS段在应用程序的二进制映像文件中并不存在。

特点:可读写。
data段:又称为数据段,通常是指用来存放程序中已被初始化的全局变量,常量,静态变量的一块内存区域。也就是我们通常说的静态存储区。

例:

#include<xxx.h>
int bss_value1=5;//全局的被初始化的变量,处于data段
int main()
{
…;
return 0;
}

注意:data段为数据分配空间,数据保存在目标文件中。

特点:可读写。
text段 (textsegment):通常指用来存放程序执行代码的一块内存区域,这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。
在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

特点:只读

rodata段:该段也叫常量区,用于存放常量数据,ro就是read only(只读)。

例:

#include<xxx.h>
//int bss_value1=5;//全局的被初始化的变量,处于data段
//const int bss_value1=5;//加上const变为只读的常量,处于rodata段
int main()
{
//…;
return 0;
}

注意:并不是所有的常量都放在常量数据段,特殊情况如下

(1):有些立即数与指令编译在一起放在代码段

(2):对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份拷贝。
c语言中const修饰的局部变量和全局变量存放在哪个区域

分析

以下皆是个人见解

int A;        //全局未初始化变量      bss
int B=0;      //全局初始化为0的变量    bss
int C=2;      //全局初始化变量       data
static int D;     //全局静态未初始化变量   bss
static int E=0;   //全局静态初始化为0的变量    bss
static int F=4;   //全局静态初始化变量         data
const  int G=5;   //全局常量                   rodata
const char H=6;                                 rodata
int main(void){
  int a;       //局部未初始化变量            stack
  int b=0;           //局部初始化为0的变量   stack
  int c=2;           //局部初始化变量        stack
  static  int d;     //局部静态未初始化变量     bss
  static  int e=0;      //局部静态初始化为0的变量  bss
  static int f=4;       //局部静态初始化变量   data
  const int g=5;        //局部常量            stack
  char  char1[] = "abcde";//局部字符串数组     stack
  char  *cptr="123456";   //p在栈上,123456在常量区
  int *heap=malloc(sizeof(int)*4);//堆
  //...
}




5. 如何查看编译、链接后的汇编代码?

通过objdump命令

1) 查看编译后的汇编代码

 objdump -d test.o -Mintel //intel 汇编格式

2)查看链接后的汇编代码

 objdump -d test -Mintel //intel 汇编格式

进行对比,说明编译到底做了什么,链接做了什么?

相关文章
|
4月前
|
人工智能 安全 Java
「星辰启明时 代码绘鸿图」Harmony OS Next
万物互联时代,开发者面临多设备适配、技术门槛高、协作难等挑战。华为HarmonyOS提供破局之道:一次开发多端部署、无缝流转、AI加持与安全保障。通过DevEco Studio,新手也能10分钟打造首个APP,从简单页面到多页跳转轻松实现。无论Windows还是Mac,安装配置简便,官方文档和资源助力快速入门,让创意变为现实。
113 5
|
10月前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
139 4
|
6月前
|
弹性计算 人工智能 运维
摆脱繁琐命令-让运维更加流畅-阿里云ECS操作系统控制台运维篇
阿里云操作系统控制台提供了便捷的服务器监控与管理功能,简化了运维工作。通过将多台服务器纳入统一监控平台,用户可以快速查看CPU、内存、磁盘和网络等关键资源的使用情况,避免了逐一远程连接查询的繁琐操作。此外,该工具支持自动化数据汇总,极大地方便了日报、周报和月报的编写。测试过程中,系统展示了良好的稳定性和响应速度,尤其在网络抖动和大文件健康状态测试中表现出色。整体体验流畅,显著提升了运维效率。 操作系统控制台地址:[点击访问](https://alinux.console.aliyun.com/)
176 26
摆脱繁琐命令-让运维更加流畅-阿里云ECS操作系统控制台运维篇
|
8月前
|
弹性计算 前端开发 Ubuntu
OS Copilot全命令测评报告
作为一名Web前端工程师,我使用OS Copilot的`-t`、`-f`和`|`功能进行了测试。通过创建ECS实例并安装OS Copilot,我顺利完成了以下任务: 1. 环境搭建:使用`-t`参数获取了详细的静态页面发布步骤,解决了环境配置问题 2. 多步操作:借助`-f`参数自动化安装和配置httpd服务器,简化了多步骤操作 3. 文件分析:利用`|`功能分析HTML文件内容,确认是否符合预期 整个过程顺畅无阻,特别是`-t`和`-f`功能极大提高了工作效率。建议将这些功能设为默认自带,以减少安装步骤。总结来说,OS Copilot在处理复杂任务时表现出色,提供了详尽的操作指引和自动化支持
84 8
|
12月前
|
存储 算法 安全
深入理解操作系统:从基础概念到代码实践
【9月更文挑战第23天】本文将带领读者深入探索操作系统的奥秘,从基础概念出发,逐步揭示操作系统的工作原理和设计哲学。我们将通过实际代码示例,展示操作系统如何与硬件交互、管理资源以及提供用户界面。无论你是计算机专业的学生还是对操作系统感兴趣的开发者,这篇文章都将为你打开一扇通往操作系统世界的大门。
188 16
|
存储 算法 Unix
探索操作系统:从理论到代码
【9月更文挑战第3天】操作系统是计算机的核心,它管理着硬件和软件之间的交互。本文将从理论出发,深入探讨操作系统的基本原理和功能,然后通过代码示例,展示操作系统是如何在实际中运作的。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深度理解。
106 1
|
11月前
|
Linux 编译器 C语言
./build.sh:行1: g++: 未找到命令的错误问题在centos操作系统下面如何解决
通过上述步骤,您应该能够有效地解决CentOS系统中 `g++: 未找到命令`的错误。确保软件开发环境配置得当,对于顺利执行编译脚本和日常开发工作至关重要。如果问题依然存在,考虑检查脚本内的命令路径引用是否正确,或进一步排查系统配置问题。
467 0
|
数据采集 数据可视化 数据挖掘
使用Python进行数据分析的新手指南深入浅出操作系统:从理论到代码实践
【8月更文挑战第30天】在数据驱动的世界中,掌握数据分析技能变得越来越重要。本文将引导你通过Python这门强大的编程语言来探索数据分析的世界。我们将从安装必要的软件包开始,逐步学习如何导入和清洗数据,以及如何使用Pandas库进行数据操作。文章最后会介绍如何使用Matplotlib和Seaborn库来绘制数据图表,帮助你以视觉方式理解数据。无论你是编程新手还是有经验的开发者,这篇文章都将为你打开数据分析的大门。
|
11月前
|
存储 Java iOS开发
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
116 0
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化代码,增强功能深入理解操作系统:从用户空间到内核空间的旅程
【8月更文挑战第29天】本文将引导你深入理解Python装饰器的核心概念、应用场景及其对代码的优化作用。我们将从基础使用到高级应用逐步展开,通过实例展示如何利用装饰器提升代码的可读性和复用性,同时避免常见的陷阱。

推荐镜像

更多