Windows程序员学习Linux环境内存管理

news2024/11/16 11:43:15

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows程序员如何学习Linux环境内存管理。由于很多程序在Windows环境下开发好后,还要部署到Linux服务器上去,所以作为Windows程序员有必要学习Linux环境的内存管理知识。

说到这里,我有必要更正现在一个普遍的误区,有很多人认为内存管理知识不再重要。但其实,内存管理是计算机编程最为基本的知识领域之一。如今很多的脚本语言中确实不必考虑内存如何管理, 但是这并不能说明内存管理已经不再重要。在实际的编程中,理解自己的内存管理器的能力与局限性至关重要。在C/C++语言编程中仍需进行内存管理,这种内存管理增强并提高了C/C++程序的功能和灵活性。

我们现在先要了解内存的分类。一个程序中使用到的数据都是存放在内存空间中的,那么执行一个程序,考虑其高效性和灵活性等就要合理地分配内存。根据内存空间分配方式的不同,可以将内存分为动态内存和静态内存。下面分别对动态内存和静态内存进行讲解。

动态内存

通常当用户无法确定空间大小,或者空间太大、栈上无法分配时,会采用动态内存方式分配内存。比如你要用C语言写一个图书馆借书管理系统,你是无法确定整个系统要处理多少书的借与还工作,书可能很多,也可能很少,书是1000本,还是10000本,还是100000本?你是不是无法确定总数?那怎么办,一般就要用结构体来实现一本书,用链表来实现书册的管理,对每本书的操作那就只能用动态内存分配来做,把一个结构体拿出来,修改信息后再放回链表,就可以实现图书管理。在使用动态内存时,程序员可以自行控制内存的分配和释放。关于分配多少,何时分配与释放等信息,都由程序员根据需要随时实现。

关于动态内存的使用,很多程序员采取能不使用就不使用的原则,原因在于动态内存资源的敏感性。若能够正确地使用并且利用好动态内存,自然会为程序的实现带来效率;但是一旦用不好,就有可能导致整个项目的崩溃。因此,关于动态内存的使用,不同程度的人应遵循不同的使用原则,目的是为了能够使程序安全、正确并且快速地实现其功能。

事物都是有利有弊的,动态内存也不例外。当动态内存为程序带来了巨大的效率的同时,也为程序带来了巨大的风险。使用动态内存会使内存管理变得很复杂。当程序员根据自己的需要动态地分配完内存,就可以得心应手地使用。但是,当不再使用时,切记释放所占的内存空间。所谓的内存泄露就是将内存分配后没有释放,而导致的内存空间减少的现象。计算机的内存空间是有限的,当分配了过多的内存而没有及时释放时,很有可能导致内存不够用,也就是通常所说的内存耗尽。内存分配与释放是配对的,分配的内存在哪里,使用完毕就要释放哪里的内存。在一个大型的项目中,如若多次分配内存,那么释放这些内存的顺序就成为难题。

好,这里我们遇到一个概念,就是内存泄露。我们就来仔细说说这个问题。顺便我们再讲一下内存溢出。内存泄漏(memory leak)是指程序在申请内存后,无法释放已申请的内存空间,有时一次内存泄漏就会造成一些影响,更不要说多处内存泄漏后所引发的更严重的后果。内存溢出(out of memory)指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错内存溢出。

内存泄漏的积累最终会导致内存溢出。内存溢出就是你要的内存空间超过了系统实际分配给你的空间,此时系统相当于没法满足你的需求,就会报内存溢出的错误。内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。就相当于你租了个带铁围栏的田地,你存完东西之后把铁围栏锁上之后,把钥匙丢了,那么结果就是这片田地将无法供其他人使用,也无法被回收。内存溢出问题,比方说栈,栈满时再做进栈必定产生空间溢出叫上溢,栈空时再做退栈也产生空间溢出称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。

内存溢出的原因主要有:内存中加载的数据量过于庞大,如一次从数据库取出过多数据;集合类中有对对象的引用,使用完后未清空;代码中存在死循环或循环产生过多重复的对象实体;使用的第三方软件中的BUG;启动参数内存值设定的过小。内存溢出的解决方案主要有:修改启动参数,直接增加内存。检查错误日志,查看错误前是否有其它异常或错误。对代码进行走查和分析,找出可能发生内存溢出的位置。重点排查以下几点:检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。检查代码中是否有死循环或递归调用。检查是否有大循环重复产生新对象实体。检查List、Map等集合对象是否有使用完后未清除的问题。List、Map等集合对象会始终存有对对象的引用,使得这些对象不能被回收。也可以使用内存查看工具动态查看内存使用情况。

内存泄漏的分类(按发生方式来分类)有如下几种:

常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。

静态内存

所谓静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源。程序中的各种变量,在编译源程序时系统就已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会自动释放所占用的内存空间。变量的分配与释放,都无须程序员自行考虑。不必像动态内存那样,要掌握分配内存的大小、何时分配与释放等细节,因此使用静态内存对程序员来说很方便控制。

使用静态内存减少了很多内存资源的风险,如内存泄露、内存耗尽等问题,但减少了风险的同时也带来了弊端。在使用一个数组时,静态内存会预先定义数组的大小,定义数组前并不确定数组中会存放多少数据,若在使用时,存放在数组中的数据大于数组的容量,那么,就会出现溢出问题;然而存放在数组中的数据小于数组的容量很多时,就会造成内存空间的浪费。

静态内存是由编译器来分配的,释放是由变量的作用域所决定的,即当一个变量定义在一个自定义的功能函数中时,如果这个函数结束,该变量也会随之释放。这样,使用指针由子函数向主函数传递数据类的问题就无法实现了。因为子函数中的变量在子函数结束时,就会被释放,所以无法将值带回到主函数。但是事情总会有解决的办法,那就是可以在主函数中定义变量,在子函数中使用主函数中定义的变量传递值。

动态内存与静态内存总结

动态内存与静态内存是两种不同的分配内存的方式,那么下面我们针对它们在分配方式上存在什么样的区别进行总结。

(1)静态内存的分配是在程序开始编译时完成的,不占用CPU资源;而动态内存的分配是在程序运行时完成的,动态内存的分配与释放都是占用CPU资源的。

(2)静态内存是在栈上分配的;而动态内存是在堆上分配的。

(3)动态内存分配需要指针和引用数据类型的支持,而静态内存不需要。

(4)静态内存分配是在编译前就已经确定了内存块的大小,属于按计划分配内存;而动态内存的分配是在程序运行过程中,根据需要随时分配的,属于按需分配。

(5)静态内存的控制权是交给编译器的,而动态内存的控制权是由程序员决定的。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/376209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机三级网络技术】 第三篇 IP地址规划技术

IP地址规划技术 文章目录IP地址规划技术一、IP 地址规划以及划分地址新技术1.IP地址的标准分类(第一阶段)2.划分子网的三级地址结构(第二阶段)3.构成超网的无类域间路由技术(第三阶段)4.网络地址转换技术(第四阶段)二、IP 地址分类1.A类、B类与C类IP地址…

数据的表示和运算

文章目录数制与编码进制间的转换BCD码定点数与浮点数定点数是什么?浮点数是什么?定点数与浮点数的区别机器数和真值原码、反码、补码、移码基本定义整数的加减法刷题小结最后数制与编码 进制间的转换 二进制、八进制、十进制、十六进制之间的转换不用多…

前端杂学1

1.简单且必须掌握的 1.MVVM是什么 将MVC中的V变为了MVVM,实现了双向绑定。其中VM就是vue的作用,这样页面的动态化可以通过vue来操作,而不是页面直接与后端操作,实现了前后端的分离 2.为什么vue采用异步渲染 ? 调…

Kubernetes之服务发现

本文使用wordpressmysql搭建个人博客来讲解服务发现相关知识。 环境准备 wordpress需要连接到mysql才能正常工作,所以需要为mysql的pod创建一个mysql的svc,只要不删除重建svc,其IP不会变。 此时wordpress的pod需要连接mysql的svc的时候&…

HyperGBM用4记组合拳提升AutoML模型泛化能力

本文作者:杨健,九章云极 DataCanvas 主任架构师 如何有效提高模型的泛化能力,始终是机器学习领域的重要课题。经过大量的实践证明比较有效的方式包括: 利用Early Stopping防止过拟合通过正则化降低模型的复杂度使用更多的训练数…

第四阶段01-酷鲨商城项目准备

1. 关于csmall-product项目 这是“酷鲨商城”大项目中的“商品管理”项目,是一个后台管理项目(给管理员,或运营人员使用的项目,并不是普通用户使用的),并且,只会涉及与发布商品可能相关的功能开…

企业工程项目管理系统平台(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

React(二):jsx事件绑定、条件渲染、列表渲染、jsx的本质、购物车案例

React(二)一、jsx事件绑定1.this的绑定方式2.jsx中绑定this的三种方式3.事件对象和传参(1)事件对象怎么传(2)其他参数怎么传?二、条件渲染1.直接if-else2.三元表达式3.利用逻辑中断4.案例练习5.…

HTML#5表单标签

一. 表单标签介绍表单: 在网页中主要负责数据采集功能,使用<form>标签定义表单表单项: 不同类型的input元素, 下拉列表, 文本域<form> 定义表单<input> 定义表单项,通过typr属性控制输入形式<label> 为表单项定义标注<select> 定义下拉列表<o…

【GO】31.grpc 客户端负载均衡源码分析

这篇文章是记录自己查看客户端grpc负载均衡源码的过程&#xff0c;并没有太详细的讲解&#xff0c;参考价值不大&#xff0c;可以直接跳过&#xff0c;主要给自己看的。一.主要接口&#xff1a;Balancer Resolver1.Balancer定义Resolver定义具体位置为1.grpc源码对解析器(resol…

异步通知实验

目录 一、异步通知简介 阻塞、非阻塞、异步通知区别 信号与信号修改测试 测试 二、驱动编写 1、定义fasync_struct 结构体指针变量 2、操作集添加fasync 3、实现imx6uirq_fasync 函数 4、关闭驱动文件操作 ​编辑 5、定时器处理函数 三、编写APP 1、编写信号的处理…

ElasticSearch 学习笔记总结(二)

文章目录一、ES JavaAPI 环境准备二、ES JavaAPI 索引1. 索引 创建2. 索引 查找3. 索引 删除三、ES JavaAPI 文档1. 文档 创建2. 文档 修改3. 文档 查询4. 文档 删除4. 文档 批量新增 和 批量删除5. 高级查询 索引全量查询6. 高级查询四、ES 集群1. ES集群 概念2. window 集群搭…

阿里P8:做测试10年我的一些经验分享,希望你们少走弯路

我是在2015年毕业的&#xff0c;当时是读的普通本科&#xff0c;不上不下的专业水平&#xff0c;毕业的时候&#xff0c;恰好遇到了金融危机。校园招聘里阴差阳错的巧合&#xff0c;让我走上了软件测试工程师的道路。 入职第一天&#xff0c;来了个高大上的讲师&#xff0c;记…

如何使用码匠连接 PostgreSQL

目录 在码匠中集成 PostgreSQL 在码匠中使用 PostgreSQL 关于码匠 PostgreSQL 是一种特性非常齐全的自由软件的对象-关系型数据库管理系统&#xff08;ORDBMS&#xff09;&#xff0c;它具有许多强大的功能&#xff0c;PostgreSQL 支持大部分的 SQL 标准并且提供了很多其他现…

一些无线通信系统模型的概念

一些无线通信系统模型的概念 扩频通信,指的是系统的带宽WWW远大于其信息传输速率R(bits/s)R(bits/s)R(bits/s), 定义展频带因子BeWRB_e \frac{W}{R}Be​RW​, 易知在扩频通信系统中,BeB_eBe​远大于1. 在频率上产生如此大的冗余度,主要是为了减轻无线通信或卫星通信中经常产生…

关于算法学习和刷题的建议

大家好&#xff0c;我是方圆。最近花时间学了学算法&#xff0c;应该算是我接触Java以来第一次真正的学习它&#xff0c;这篇帖子我会说一些我对算法学习的理解&#xff0c;当然这仅仅是浅浅的入算法的门&#xff0c;如果想深挖或者是有基础的人想提升自己&#xff0c;我觉得这…

【Linux】内核同步机制之等待队列和完成量

文章目录完成量和等待队列1. 等待队列1.1 基本元素1.2 等待队列的创建和初始化1.3 等待队列元素的创建和初始化1.4 添加和移除等待队列元素到等待队列2. 等待事件机制3. 等待队列唤醒4. 总结4.1 等待事件方式4.2 手动休眠方式4.3 借助内核封装函数&#xff0c;进行手动休眠5. 完…

前端开发_快应用开发

目录快应用官网真机调试组件组件嵌套问题tab组件list组件web组件css 样式问题[1]选择器[2]盒模型[3]样式布局-弹性布局[4-1]样式切换 - 类名的动态切换[4-2] 样式切换 - 行内样式动态切换[5]background[6]overflow[7]border-radius[8]盒子阴影[9] 单位系统接口[1] 检查某app是否…

机房运维6大隐患,你中了几个?

随着医院的看诊预约、缴费、打印报告等众多业务转至线上进行&#xff0c;对医院的网络及数据处理能力提出越来越高的要求&#xff0c;那么&#xff0c;机房的稳定、安全运行是医院网络信息系统的关键因素。 机房运维6大隐患 01.电源电力系统不稳定&#xff0c;网络设备运转遭到…

华为面试题就这?00后卷王直接拿下30k华为offer......

先说一下我的情况&#xff0c;某211本计算机&#xff0c;之前在深圳那边做了大约半年多少儿编程老师&#xff0c;之后内部平调回长沙这边&#xff0c;回来之后发现有点难&#xff0c;这边可能是业绩难做&#xff0c;虚假承诺很厉害&#xff0c;要给那些家长虚假承诺去骗人家&am…