当前位置: 首页 > news >正文

Linux笔记 --- 内存管理

        在程序中我们访问的内存地址都是从物理内存上映射而来的虚拟地址,假设我们使用的计算机实际物理内存(PM)只有1GB,而Linux中执行着三个进程,Linux会将PM中的某段内存映射成三段4G大小相同的虚拟内存(VM),让每个进程都认为得到了需要的完整内存

进程内存布局

        在虚拟内存中内存是被分配给不同的部分的,具体每部分存储的内容如下图

对该图做几点说明:

1,栈中的环境变量和命令行参数在程序一开始运行之时就被固定在了栈底(即紧挨着内核的地方),且在进程在整个运行期间不再发生变化,假如进程运行时对环境变量的个数或者值做了修改,则为了能够容纳修改后的内容,新的环境变量将会被拷贝放置到堆中。

2,栈还有一个名称叫做“堆栈”,这是中文比较奇葩的地方:“堆栈”跟“堆”没有半毛钱关系。

3,栈和堆都是动态变化的,分别向下和向上增长,大小随着进程的运行不断变大变小。

4,静态数据指的是:所有的全局变量,以及static 型局部变量。

5,数据段的大小在进程一开始运行就是固定的,其中.rodata存放程序中所有的常量,.data存放所有的静态数据,而如果静态数据未被初始化,则程序刚开始运行时系统将会自动将他们统统初始化为0然后放置在.bss段中,这么做的原因是要节省磁盘存储空间:由于未初始化的静态数据在运行时一概会被初始化为0,因此在程序文件中就没有必要保存任何未初始化的变量的值了

6,如果没有一个极具说服力的理由,我们应该尽量避免使用静态数据,因为滥用静态数据至少有两个缺点:第一,静态数据的生命周期跟整个进程相当,也就是说不管你什么时候需要用到他们,他们在进程一开始运行的时候就已经存在了,而且就算你不再需要他们,在进程完全退出之前他们都不会释放,会无条件地一直占用内存。第二,静态数据中的全局变量是一种典型的共享资源,尤其在多线程程序中,共享资源是滋生“竞态”的温床(详见5.x.x小节),实在没办法要在多线程程序在使用全局变量,必须仔细地使用各种同步互斥手段保护他们,而不是简单粗暴地胡乱使用。

7,用户代码所在的.text段也称为正文段,.text是一个默认的名称,他将会囊括用户定义的所有的函数代码,实际上我们可以将某些指定的函数放置到自己指定段当中去,比如在程序代码中有一段音乐数据,我们可以将此段数据放置在一个.mp3的代码段当中(详见2.6.3小节),而.init段是存放的系统初始化代码,这部分代码之所以要放置在.init段是因为这个段当中的代码默认只会被执行一遍(初始化只能执行一遍),完成任务之后所占据的内存会被立即释放,以便节省系统资源,因此我们自己定义的函数如果也是在进程开始之初只执行一遍就不再需要,那么也可以将之放置在该段中。

堆(heap)

        堆内存被称为内存中的自由区,这是一个非常重要的区域,因为在此区定义的内存的生命周期我们是可以控制的域,对比其他区域的内存则不然,比如栈内存,栈的特点就是临时分配临时释放,一个变量如果是局部变量,他就会被定义在栈内存中,一旦这个局部变量所在的函数退出,不管你愿不愿意该局部变量也就会被立即释放,再如静态数据,他们都被存储在数据段,如前所述,这些变量将一直占用内存直到进程退出为止。

        堆内存的生命周期是:从malloc( )/calloc( )/realloc( )开始,到free( )结束,其分配和释放完全由我们开发者自定义,这就给了我们最大的自由和灵活性,让程序在运行的过程当中,以最大的效益使用内存。

        对堆操作的函数介绍如下

 堆最大的特点是自定义其生命周期,除了调用free(),不会因为所在函数退出而释放

此处增加一个示例表明使用方法

#include <stdio.h>
#include <stdlib.h>int *heap_array(int *old_ptr,int n);
void show(int *ptr);int main(int argc, char const *argv[])
{int n , *p = (int*)malloc(1 * sizeof(int));//分配一块int类型大小的内存p[0] = 1;while (1){if(scanf("%d",&n) == 0)//输入非数字则退出break;p = heap_array(p , n);//输入数字则扩展内存并将数字填入最新的堆show(p);}free(p);return 0;
}int *heap_array(int *old_ptr,int n)
{int size,*new_ptr;size = old_ptr[0]+1;new_ptr =(int*) realloc(old_ptr , size * sizeof(int));new_ptr[0] = size;new_ptr[size - 1] = n;return new_ptr;
}void show(int *ptr)
{printf("---> ");for (int i = 1; i < ptr[0]; i++){printf("%d ",ptr[i]);}printf("<---\n");}

相关文章:

Linux笔记 --- 内存管理

在程序中我们访问的内存地址都是从物理内存上映射而来的虚拟地址&#xff0c;假设我们使用的计算机实际物理内存&#xff08;PM&#xff09;只有1GB&#xff0c;而Linux中执行着三个进程&#xff0c;Linux会将PM中的某段内存映射成三段4G大小相同的虚拟内存&#xff08;VM&…...

树莓派通过webRTC进行视频流传输到公网

为了实现树莓派和浏览器之间的视频流传输&#xff0c;你需要在公网服务器上运行 Node.js 的信令服务器&#xff0c;同时在树莓派上运行 Node.js 客户端代码。以下是具体的步骤和说明&#xff1a; 1. 公网服务器 安装 Node.js&#xff1a;在公网服务器上&#xff0c;你需要安装…...

【数据结构与算法】循环队列

循环队列 一.循环队列的引入二.循环队列的原理三.循环队列判断是否为满或空1.是否为空2.是否为满 四.循环队列入队五.循环队列出队六.循环队列的遍历七.循环队列获取长度八.总结 一.循环队列的引入 还记得我们顺序队列的删除元素嘛,我们有两种方式,一种是将数组要删除元素后面…...

为什么推荐使用@RequiredArgsConstructor代替@Autowired?

首先说一下前提&#xff1a; 项目中已经使用了Lombok&#xff0c;否则添加 Lombok 可能会增加项目的复杂度和构建时间。如果依赖项是可选的或可能在运行时改变&#xff0c;则使用字段注入或 setter 注入可能更为合适。 正文&#xff1a; 在 Spring 框架中&#xff0c;Autowir…...

ARM系列运行异常排查

一、断点指令BKPT BKPT指令产生软件断点中断&#xff0c;可用于程序的调试。它使处理器停止执行正常指令&#xff08;使处理器中止预取指&#xff09;而进入相应的调试程序。 BKPT指令的格式为&#xff1a;BKPT 16位的立即数 二、使用BKPT进行软件异常定位 假设异常发生后…...

Hive3:库操作常用语句

1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …...

C语言实现:C51单片机驱动LCD屏幕显示字符串(Proteus+Keil)

在Proteus中绘制电路原理图 我使用的版本是Protues8.16 ,Protues特别擅长仿真单片机及其外围设备&#xff0c;支持多种类型的微控制器&#xff0c;如8051、HC11、PIC、AVR、ARM、MSP430等&#xff0c;也可以设计pcb板&#xff0c;还能3D建模 1.新建工程 在 Start 栏中点击 …...

暄桐好作业之《临沈周〈东庄图册〉局部》

暄桐是一间传统美学教育教室&#xff0c;创办于2011年&#xff0c;林曦是创办人和授课老师&#xff0c;教授以书法为主的传统文化和技艺&#xff0c;皆在以书法为起点&#xff0c;亲近中国传统之美&#xff0c;以实践和所得&#xff0c;滋养当下生活。      其中“暄桐好作…...

Qt3D创建3D物体步骤

使用Qt3D接口创建3D物体的步骤大致有以下几步: 1.创建一个3D窗口 2.创建根实体 3.创建物体实体,父指针为根实体 4.创建立体图形,即物体网格,设置物体的属性 5.给立体图形添加材质,添加坐标位置,添加纹理,添加其他效果 6.创建摄像头,设置摄像头的属性,父指针为根…...

UDP程序设计

UDP协议概述 UDP&#xff0c;User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;是一个简单的面向数据报(package-oriented)的传输层协议&#xff0c;规范为&#xff1a;RFC 768。 UDP提供数据的不可靠传递&#xff0c;它一旦把应用程序发给网络层的数据发送出去…...

计算机网络—电路、分组、报文交换—图文详解

计算机网络—电路、分组、报文交换 计算机网络中的数据传输方式可以根据数据的处理方式和网络资源的使用方式分为电路交换、分组交换和报文交换三种类型。 这些方式在网络设计和数据传输过程中起到了不同的作用和效果。 1. 电路交换&#xff08;Circuit Switching&#xff0…...

linux下交叉编译licensecc

本文章只做个人笔记用 下载地址&#xff1a; #https://github.com/open-license-manager/licensecc.git #下面地址下不下来就是用第一个去官网下载git clone --recursive https://github.com/open-license-manager/licensecc.git 编译前准备3个库&#xff1a;openssl&#x…...

模型剪枝综述

目录 1 深度神经网络的稀疏性&#xff1a; 2 剪枝算法分类&#xff1a; 3 具体的剪枝方法包括&#xff1a; 4 剪枝算法流程&#xff1a; 5 几种常见的剪枝算法&#xff1a; 6 结构化剪枝和非结构化剪枝各有其优缺点&#xff1a; 7 剪枝算法对模型精度的影响 8 影响剪枝…...

破解监控难题,局域网电脑监控软件哪家强?

现在的环境&#xff0c;企业要想茁壮成长&#xff0c;员工的高效工作那可是关键中的关键。但不少老板都发现了一个头疼的问题&#xff0c;员工上班老是偷懒&#xff0c;这可怎么行&#xff1f;今天&#xff0c;就来给大家详细说道说道几款出色的局域网电脑监控软件&#xff0c;…...

Linux--Socket编程TCP

前文&#xff1a;Socket套接字编程 TCP的特点 面向连接&#xff1a;TCP 在发送数据之前&#xff0c;必须先建立连接。可靠性&#xff1a;TCP 提供了数据传输的可靠性。面向字节流&#xff1a;TCP 是一个面向字节流的协议&#xff0c;这意味着 TCP 将应用程序交下来的数据看成是…...

Android Studio导入源码

在有源码并且编译环境可用的情况下&#xff1a; 1.生成导入AS所需的配置文件 在源码的根目录执行以下命令&#xff1a; source build/ensetup.sh lunch 要编译的项目 make idegen //这一步会生成out/host/linux-x86/framework/idegen.jar development/tools/idegen/idegen.sh…...

UE5 UE4 使用python进行编辑器操作

使用UE 4.25以上版本后&#xff0c;python代码改动相对较少。 如下类库在4.20/21/22等早起版本不适用&#xff0c;建议查询UE的python文档 unreal.EditorAssetLibrary 1.获取当前选中的资源&#xff08;Content中&#xff09; # 获取当前选中的资产selected_assets unreal.E…...

区块链技术在智能城市中的创新应用探索

随着全球城市化进程的加速和信息技术的快速发展&#xff0c;智能城市成为了未来城市发展的重要方向。在智能城市建设中&#xff0c;区块链技术作为一种去中心化、安全和透明的分布式账本技术&#xff0c;正逐渐展现出其在优化城市管理、提升公共服务和增强城市安全性方面的潜力…...

解决mysql事件调度器重启服务后自动失效的问题

前段时间为通过mysql事件生成测试数据&#xff0c;今天发现数据在10:57后停止了CREATE EVENT IF NOT EXISTS insert_random_data ON SCHEDULE EVERY 10 SECOND DO INSERT INTO test (createtime, random_number) VALUES (NOW(), FLOOR(RAND() * 100));检查事件状态&#…...

mybatis开启二级缓存

例子 mybatis-config.xml <configuration><settings><setting name"cacheEnabled" value"true"/></settings><environments default"development"><environment id"development"><transacti…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...