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

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

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

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 汇编格式

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

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
2月前
|
存储 算法 安全
深入理解操作系统:从基础概念到代码实践
【9月更文挑战第23天】本文将带领读者深入探索操作系统的奥秘,从基础概念出发,逐步揭示操作系统的工作原理和设计哲学。我们将通过实际代码示例,展示操作系统如何与硬件交互、管理资源以及提供用户界面。无论你是计算机专业的学生还是对操作系统感兴趣的开发者,这篇文章都将为你打开一扇通往操作系统世界的大门。
67 16
|
1月前
|
Linux 编译器 C语言
./build.sh:行1: g++: 未找到命令的错误问题在centos操作系统下面如何解决
通过上述步骤,您应该能够有效地解决CentOS系统中 `g++: 未找到命令`的错误。确保软件开发环境配置得当,对于顺利执行编译脚本和日常开发工作至关重要。如果问题依然存在,考虑检查脚本内的命令路径引用是否正确,或进一步排查系统配置问题。
103 0
|
1月前
|
存储 Java iOS开发
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
30 0
|
2月前
|
存储 算法 Unix
探索操作系统:从理论到代码
【9月更文挑战第3天】操作系统是计算机的核心,它管理着硬件和软件之间的交互。本文将从理论出发,深入探讨操作系统的基本原理和功能,然后通过代码示例,展示操作系统是如何在实际中运作的。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深度理解。
|
4月前
|
弹性计算 运维
阿里云操作系统智能助手OS Copilot实验测评报告
**OS Copilot 产品体验与功能反馈摘要** 运维人员发现OS Copilot易上手,文档清晰,助其高效排查故障(8/10分)。愿意推荐并参与开源开发。亮点在于知识问答,能快速筛选答案。相较于竞品,优点是新手友好、文档清晰,但功能扩展性待增强。期望增加系统错误排查与解决方案,并集成ECS等,以优化系统安装流程。
阿里云操作系统智能助手OS Copilot实验测评报告
|
3月前
|
数据采集 数据可视化 数据挖掘
使用Python进行数据分析的新手指南深入浅出操作系统:从理论到代码实践
【8月更文挑战第30天】在数据驱动的世界中,掌握数据分析技能变得越来越重要。本文将引导你通过Python这门强大的编程语言来探索数据分析的世界。我们将从安装必要的软件包开始,逐步学习如何导入和清洗数据,以及如何使用Pandas库进行数据操作。文章最后会介绍如何使用Matplotlib和Seaborn库来绘制数据图表,帮助你以视觉方式理解数据。无论你是编程新手还是有经验的开发者,这篇文章都将为你打开数据分析的大门。
|
3月前
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化代码,增强功能深入理解操作系统:从用户空间到内核空间的旅程
【8月更文挑战第29天】本文将引导你深入理解Python装饰器的核心概念、应用场景及其对代码的优化作用。我们将从基础使用到高级应用逐步展开,通过实例展示如何利用装饰器提升代码的可读性和复用性,同时避免常见的陷阱。
|
4月前
|
弹性计算 运维 自然语言处理
阿里云操作系统智能助手OS Copilot实验测评报告
OS Copilot是针对Linux的智能助手,助力学习、运维及编程。用户界面直观,自然语言交互方便新手。官方文档详尽,但初次配置略复杂,适合学生和开发者。在提高代码编写和调试效率、系统学习上得分高,功能亮点包括代码生成、问答和命令执行。用户期待更多操作系统支持、自动错误分析和系统排查功能。
184 3
|
4月前
|
弹性计算 人工智能 运维
阿里云操作系统智能助手OS Copilot实验测评报告
阿里云操作系统智能助手OS Copilot实验测评报告
110 2
|
4月前
|
Unix API 数据格式
云计算存储问题之API在不同操作系统上的实现如何解决
云计算存储问题之API在不同操作系统上的实现如何解决

热门文章

最新文章