【进程与线程】程序和进程在内存中的表现
在计算机系统中,程序和进程是两个密切相关但又有本质区别的概念,尤其在内存中的表现上有显著不同:

在这张图中可以直观地看出程序和进程在内存中的结构区别。
基本定义
程序
程序 是一个 静态实体,表示一组写好的指令和数据的集合,一般存储在磁盘上(如 .exe、.out 文件)。程序本身不占用运行时的系统资源(如 CPU、内存等),它是一个静态文件,它仅包含代码和数据的固定内容,表示完成某种任务的一组指令集合。
- 程序的特性:
- 静态性:程序只是存储在磁盘中的文件,不会动态变化(程序是静态的文件,不占用运行时资源)。
- 无运行环境:程序没有运行时需要的栈、堆、寄存器等概念(程序没有运行时动态分配的内存(如堆和栈))。
- 程序本身不包含对操作系统资源(如 CPU、内存)的使用能力。
进程
- 进程是程序运行后的动态实例,是操作系统分配资源的基本单元;进程是程序的一次执行实例,是一个动态实体。
- 进程是程序运行后的产物,程序一旦被加载到内存并运行,就变成了进程。
- 进程需要操作系统的支持,每个进程都有独立的虚拟地址空间,并占用实际的运行时资源(如内存、CPU、文件描述符等)。
程序是静态代码,进程是动态运行的程序实例。 一个程序可以对应多个进程(如多次运行同一个程序)。
程序和进程在内存中的区别
程序的内存布局:一个程序在磁盘上是静态的,存储的内容包括:
- 代码段:
- 包含程序的指令集(如函数实现、逻辑代码)。
- 代码段是只读的,防止运行时修改。
- 多个进程可以共享同一份代码段,节省内存资源。
- 数据段:
- 包含程序中的全局变量和静态变量的初始值。
- 数据段是可写的,但内容固定,程序编译时就固定下来,程序静态存在时不会动态变化。
进程的内存布局:
当程序运行后,进程会被加载到内存中,成为一个动态实体。操作系统为每个进程分配一个独立的虚拟地址空间,通常包括以下部分(如图所示):
- 代码段:
- 与程序中的代码段一致,存储程序的指令集(通常是只读的)。
- 多个运行同一程序的进程可以共享该段,节省内存。
- 数据段:
- 存储进程运行时的全局变量和静态变量。
- 每个进程的这部分独立存在,不同进程之间互不影响。
- 堆区:
- 堆是运行时动态分配的内存区域,通过 malloc 或 new 等函数分配。
- 堆区是进程运行时动态分配的,大小不固定。
- 堆的大小可以动态增长或缩减,主要用于存储动态对象或数据。
- 栈区:
- 栈用于存储函数调用的局部变量、返回地址以及函数调用的上下文信息。
- 栈的大小在运行时动态变化(通常从高地址向低地址增长)。
- 内核空间:
- 进程虚拟地址空间的高地址部分通常保留给操作系统内核使用(如图中 1GB:内核空间位于进程的虚拟地址空间的高地址部分)。
- 用于存储操作系统内核的数据和代码,用户进程无法直接访问内核空间,必须通过系统调用与内核交互。
图示中已经表明了二者的关键区别:
- 程序:
- 静态结构,存储在磁盘中。
- 没有动态分配的堆和栈。
- 包含固定的代码段和数据段。
- 程序是进程的模板,只有加载到内存并运行后,程序才变成进程。
- 进程:
- 动态结构,在内存中运行。
- 包含动态分配的堆和栈,用于运行时的内存管理。
- 进程的每一部分(如堆、栈、数据段)都是独立的,其他进程访问不到。
- 有操作系统分配的虚拟地址空间(如 4GB),包括用户空间和内核空间。
内存分布的对比
| 内存区域 | 程序(静态) | 进程(动态) |
|---|---|---|
| 代码段 | 包含程序的指令集,内容固定。 | 包含程序的指令集,可能被多个进程共享。 |
| 数据段 | 包含全局变量和静态变量的初始值,固定。 | 包含全局变量和静态变量的实际值,独立分配。 |
| 堆区 | 无堆区。 | 动态分配的内存区域,大小运行时变化。 |
| 栈区 | 无栈区。 | 存储局部变量、函数调用信息,动态变化。 |
| 内核空间 | 无操作系统内核相关内容。 | 包含与操作系统交互的内核数据。 |
特性区别:
| 特性 | 程序 | 进程 |
|---|---|---|
| 静态/动态 | 静态实体,存储在磁盘中 | 动态实体,是程序在运行时的实例 |
| 文件类型 | 可执行文件(如 .exe、.out) | 运行时的实例,操作系统分配 ID(PID)标识 |
| 内存结构 | 只包含代码段和数据段 | 包含代码段、数据段、堆、栈和内核空间 |
| 资源使用 | 不占用系统资源 | 占用内存、CPU、文件描述符等运行时资源 |
| 并发性 | 程序本身不可并发 | 一个程序可以对应多个进程(不同的运行实例) |
| 生命周期 | 静态存储在磁盘上,永久存在 | 动态创建和销毁,随运行状态变化 |
| 共享性 | 所有进程共享同一个程序文件 | 每个进程有独立的虚拟地址空间 |
实际代码:假设有一个程序 example.c:
#include <stdio.h>
#include <stdlib.h>int global_var = 10; // 全局变量int main() {int local_var = 20; // 局部变量int *dynamic_var = malloc(sizeof(int)); // 动态分配的变量*dynamic_var = 30;printf("global_var: %d\n", global_var);printf("local_var: %d\n", local_var);printf("dynamic_var: %d\n", *dynamic_var);free(dynamic_var);return 0;
}
程序的内存结构:
当程序编译完成后,生成一个可执行文件 example.out,它在磁盘上的结构如下:
- 代码段:包含 main 函数和 printf 的指令。
- 数据段:包含 global_var 的初始值 10。
进程的内存结构:
当运行 ./example.out 时,操作系统为其创建一个进程,分配内存结构如下:
- 代码段:包含 main 函数的指令,多个进程共享该段。
- 数据段:存储 global_var 的值 10,每个进程有独立的副本。
- 堆区:malloc 分配的内存,存储 dynamic_var 的值 30。
- 栈区:存储局部变量 local_var 的值 20 和函数调用信息。
- 内核空间:包含内核相关的信息(如文件描述符、上下文切换等)。
程序和进程的区别进一步体现了两者的动态行为在内存使用的表现上:
程序的运行流程:
- 程序最初是存储在磁盘上的静态文件(如
example.out)。 - 操作系统将程序加载到内存,分配代码段和数据段。
- 程序在未运行时,不涉及堆和栈的动态分配。
进程的运行流程:
- 操作系统为进程分配独立的虚拟地址空间(如 4GB 空间)。
- 代码段加载到内存中,多个进程可以共享代码段。
- 数据段初始化全局变量和静态变量。
- 运行时,进程会动态请求堆内存(如
malloc)。 - 每次函数调用时,进程为局部变量和返回地址分配栈空间。
程序和进程的运行流程
程序的生命周期:
- 编写源代码(
.c文件)。 - 编译生成可执行文件(如
.out)。 - 程序静态存储在磁盘中,等待被加载运行。
进程的生命周期:
- 创建:程序被加载到内存中,操作系统分配 PCB(进程控制块)(想了解这个东西详细查看文章:进程控制块)和 虚拟地址空间。
- 运行:进程获得 CPU 执行权,进入运行状态。
- 等待:进程可能因 I/O 操作或资源不足进入等待状态。
- 销毁:进程执行完毕或被操作系统终止,释放资源。
简单的记忆:
- 程序是静态的文件,存储在磁盘上,不占用运行时资源。
- 进程是程序运行时的实例,有独立的虚拟内存空间,包含动态分配的堆、栈和运行时上下文。
- 内存结构:
- 程序只包含代码段和数据段。
- 进程包含代码段、数据段、堆、栈和内核空间。
通过程序和进程的对比,可以理解程序是代码逻辑的载体,而进程是操作系统管理的运行实体。两者结合才能实现计算任务的执行。更简单的说:程序是模板,进程是运行实例。 程序的静态结构在加载后被操作系统动态扩展为进程的完整内存结构。
以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。
我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!
相关文章:
【进程与线程】程序和进程在内存中的表现
在计算机系统中,程序和进程是两个密切相关但又有本质区别的概念,尤其在内存中的表现上有显著不同: 在这张图中可以直观地看出程序和进程在内存中的结构区别。 基本定义 程序 程序 是一个 静态实体,表示一组写好的指令和数据的…...
个人主页搭建全流程(Nginx部署+SSL配置+DCDN加速)
前言 最近开始准备秋招,打算做一个个人主页,以便在秋招市场上更有竞争力。 目前,现有的一些搭建主页的博文教程存在以下一些问题: 使用Github Page进行部署,这在国内访问容易受阻使用宝塔面板等框架,功能…...
语音合成的预训练模型
语音合成的预训练模型 与 ASR(语音识别)和音频分类任务相比,语音合成的预训练模型检查点明显较少。在 Hugging Hub 上,可以找到近 300 个适合的检查点。 在这些预训练模型中,重点关注两种在 Huggingface Transformers 库中开箱即用的架构——SpeechT5 和 Massive Multili…...
前端组件开发:组件开发 / 定义配置 / 配置驱动开发 / 爬虫配置 / 组件V2.0 / form表单 / table表单
一、最早的灵感 最早的灵感来自sprider / 网络爬虫 / 爬虫配置,在爬虫爬取网站文章时候,会输入给爬虫一个配置文件,里边的内容是一个json对象。里边包含了所有想要抓取的页面的信息。爬虫通过这个配置就可以抓取目标网站的数据。其实本文要引…...
Swagger生成Api文档的增强解决方案--knife4j
方法一: 使用步骤 1.导入 knife4j 的maven坐标 在pom.xml中添加依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.5.0</ver…...
Node.js - HTTP
1. HTTP请求 HTTP(Hypertext Transfer Protocol,超文本传输协议)是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端(通常是浏览器、手机应用或其他网络工具)发送给服务器的消息,用来请求资源或执行…...
LangChain学习笔记2 Prompt 模板
安装 langchain 库 pip install langchain1、概念:提示和提示工程 在大语言模型(LLMs)时代,通过简单地更改提示中的指令,同一个模型可以执行多种任务。这一特性让 LLMs 在各类应用场景中都显得非常灵活和强大。然而&…...
如何在gitlab cicd中实现每月10号上午执行
在 GitLab CI/CD 中,可以通过设置定时触发器(Schedules)和脚本中的时间判断逻辑结合,确保任务只在每月 10 号的上午运行。 以下是实现的步骤: 1. 设置定时触发器 GitLab 提供了 Schedules 功能,可以指定每…...
SimpleFOC |SimpleFOC学习笔记汇总
在机器人领域,掌握无刷电机的控制相当于掌握机器人设计的“半壁江山”。这个年代,对个人来说学习一种新技术最好是通过开源项目了。通过开源项目快速将项目搭建起来,接着结合实践与理论才能真正掌握技术。 入门FOC,我认为最合适是…...
OpenArk64:Windows 系统分析与逆向工程工具详解
引言 在 Windows 系统的底层操作和逆向工程领域,OpenArk 是一款备受推崇的开源工具集。而 OpenArk64.exe 是 OpenArk 工具的 64 位版本,专门用于 64 位 Windows 系统。它提供了强大的功能,帮助用户深入分析系统内核、进程、文件、注册表等&a…...
数据储存与管理【大数据导论】
这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川 💖文章专栏:大数据入门到进阶 🌏代码仓库: 写在开头 现在您看到的是我的结论或想法,但在这背后凝结了大量的思考、经验和讨论 目录 1…...
《从零到一:搭建高效体育直播网站的全流程技术指南》
搭建一个体育直播网站需要综合考虑技术架构、数据来源、用户体验、安全性等多个层面。从整体到细节,搭建这样一个网站的流程比较复杂,但可以分成几个重要的步骤和技术环节。以下是搭建体育直播网站的技术层面准备全流程: 一、需求分析与规划 …...
松散比较(PHP)(小迪网络安全笔记~
免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!! 附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,…...
一文了解如何使用 DBeaver 管理 DolphinDB
在日常的数据开发、分析和数据库运维中,一款优秀的 IDE 能够极大地提升工作效率。DBEaver 是一款由 Java 编写的一站式跨平台连接器,其社区版本已能支持连接近百种数据库,受到广大开发者的喜爱。近期。DolphinDB 与 DBeaver 团队共同努力&…...
网络基础知识指南|1-20个
1. IP地址: 即互联网协议地址,是用于标识互联网上的每一个设备或节点的唯一地址。IP地址的作用主要是进行网络设备的定位和路由,确保数据包可以从源设备准确地传送到目标设备。2. 子网掩码: 是用于将一个IP地址划分为网络地址和主机地址的工具。它通常与…...
01.09周四F34-Day50打卡
文章目录 1. -我大衣呢? -就在上次你放的地方。2. 这所学校是在曾经的影院上建立起来的。3. 她今天落到这个地步都怪你。4. 留得青山在,不怕没柴烧。(一息尚存,希望不灭。)5. 有善良的地方就有美德,有美德的地方就有奇迹。(《灰姑娘》原句)6. 为了和老外说话时不再发窘,所…...
Linux简介和环境搭建
Linux 介绍和环境搭建 1、发行版本 Linux 操作系统有多个主流发行版本,每个版本根据不同的目标、特点和使用场景为用户提供了不同的功能和体验。 Ubuntu • 特点:Ubuntu 是最为人熟知的 Linux 发行版之一,强调易用性和用户友好性ÿ…...
在移动端开发图表,uniapp+echarts,需要特殊处理,使用renderjs
1.首先要创建一个组件warning,用来装图表(我排除绿色那段代码为我的需求,不是必要代码) <template> <div class="task_container"> <div class="pop_body"> <div class="footer"> <warning…...
SpringBoot之LazyInitializationBeanFactoryPostProcessor类源码学习
源码分析 /**** author Andy Wilkinson* author Madhura Bhave* author Tyler Van Gorder* author Phillip Webb* since 2.2.0* see LazyInitializationExcludeFilter** 主要用于延迟初始化 Bean 的配置。它通过修改 BeanFactory 的配置来确保某些 Bean 在实际需要时才进行初始…...
United States of America三种表示
"United States of America", "United States", 和 "America" 都表示美国,但它们的使用场景和背景略有不同。以下是关于为什么这些名称可以合在一起表示美国的详细解释: 1. "United States of America" 全称&a…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
