当前位置: 首页 > news >正文 网站建设优化建议wordpress 技术文档 news 2025/10/29 17:05:33 网站建设优化建议,wordpress 技术文档,php怎么做网站程序,wordpress mysqlli#x1f387;C学习历程#xff1a;入门 博客主页#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话#xff1a; 也许你现在做的事情#xff0c;暂时看不到成果#xff0c;但不要忘记… C学习历程入门 博客主页一起去看日落吗持续分享博主的C学习历程博主的能力有限出现错误希望大家不吝赐教分享给大家一句我很喜欢的话 也许你现在做的事情暂时看不到成果但不要忘记树成长之前也要扎根也要在漫长的时光中沉淀养分。静下来想一想哪有这么多的天赋异禀那些让你羡慕的优秀的人也都曾默默地翻山越岭。 目录1. 项目介绍2. 内存池介绍3. 定长内存池的实现4. 定长内存池代码5. 性能测试1. 项目介绍 本项目实现的是一个高并发的内存池它的原型是Google的一个开源项目tcmalloctcmalloc全称Thread-Caching Malloc即线程缓存的malloc实现了高效的多线程内存管理用于替换系统的内存分配相关函数malloc和free。 tcmalloc的知名度也是非常高的不少公司都在用它比如Go语言就直接用它做了自己的内存分配器。 该项目就是把tcmalloc中最核心的框架简化后拿出来模拟实现出一个mini版的高并发内存池目的就是学习tcmalloc的精华。 该项目主要涉及C/C、数据结构链表、哈希桶、操作系统内存管理、单例模式、多线程、互斥锁等方面的技术。 2. 内存池介绍 池化技术 在说内存池之前我们得先了解一下“池化技术”。所谓“池化技术”就是程序先向系统申请过量的资源然后自己进行管理以备不时之需。 之所以要申请过量的资源是因为申请和释放资源都有较大的开销不如提前申请一些资源放入“池”中当需要资源时直接从“池”中获取不需要时就将该资源重新放回“池”中即可。这样使用时就会变得非常快捷可以大大提高程序的运行效率。 在计算机中有很多使用“池”这种技术的地方除了内存池之外还有连接池、线程池、对象池等。以服务器上的线程池为例它的主要思想就是先启动若干数量的线程让它们处于睡眠状态当接收到客户端的请求时唤醒池中某个睡眠的线程让它来处理客户端的请求当处理完这个请求后线程又进入睡眠状态。 内存池 内存池是指程序预先向操作系统申请一块足够大的内存此后当程序中需要申请内存的时候不是直接向操作系统申请而是直接从内存池中获取同理当释放内存的时候并不是真正将内存返回给操作系统而是将内存返回给内存池。当程序退出时或某个特定时间内存池才将之前申请的内存真正释放。 内存池主要解决的问题 内存池主要解决的就是效率的问题它能够避免让程序频繁的向系统申请和释放内存。其次内存池作为系统的内存分配器还需要尝试解决内存碎片的问题。 内存碎片分为内部碎片和外部碎片 外部碎片是一些空闲的小块内存区域由于这些内存空间不连续以至于合计的内存足够但是不能满足一些内存分配申请需求。内部碎片是由于一些对齐的需求导致分配出去的空间中一些内存无法被利用。 注意 内存池尝试解决的是外部碎片的问题同时也尽可能的减少内部碎片的产生。 malloc C/C中我们要动态申请内存并不是直接去堆申请的而是通过malloc函数去申请的包括C中的new实际上也是封装了malloc函数的。 我们申请内存块时是先调用mallocmalloc再去向操作系统申请内存。malloc实际就是一个内存池malloc相当于向操作系统“批发”了一块较大的内存空间然后“零售”给程序用当全部“售完”或程序有大量的内存需求时再根据实际需求向操作系统“进货”。 malloc的实现方式有很多种一般不同编译器平台用的都是不同的。比如Windows的VS系列中的malloc就是微软自行实现的而Linux下的gcc用的是glibc中的ptmalloc。 3. 定长内存池的实现 malloc其实就是一个通用的内存池在什么场景下都可以使用但这也意味着malloc在什么场景下都不会有很高的性能因为malloc并不是针对某种场景专门设计的。 定长内存池就是针对固定大小内存块的申请和释放的内存池由于定长内存池只需要支持固定大小内存块的申请和释放因此我们可以将其性能做到极致并且在实现定长内存池时不需要考虑内存碎片等问题因为我们申请/释放的都是固定大小的内存块。 我们可以通过实现定长内存池来熟悉一下对简单内存池的控制其次这个定长内存池后面会作为高并发内存池的一个基础组件。 如何实现定长 在实现定长内存池时要做到“定长”有很多种方法比如我们可以使用非类型模板参数使得在该内存池中申请到的对象的大小都是N。 templatesize_t N class ObjectPool {};此外定长内存池也叫做对象池在创建对象池时对象池可以根据传入的对象类型的大小来实现“定长”因此我们可以通过使用模板参数来实现“定长”比如创建定长内存池时传入的对象类型是int那么该内存池就只支持4字节大小内存的申请和释放。 templateclass T class ObjectPool {};如何直接向堆申请空间 既然是内存池那么我们首先得向系统申请一块内存空间然后对其进行管理。要想直接向堆申请内存空间在Windows下可以调用VirtualAlloc函数在Linux下可以调用brk或mmap函数。 #ifdef _WIN32#include Windows.h #else//... #endif//直接去堆上申请按页申请空间 inline static void* SystemAlloc(size_t kpage) { #ifdef _WIN32void* ptr VirtualAlloc(0, kpage13, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #else// linux下brk mmap等 #endifif (ptr nullptr)throw std::bad_alloc();return ptr; }这里我们可以通过条件编译将对应平台下向堆申请内存的函数进行封装此后我们就不必再关心当前所在平台当我们需要直接向堆申请内存时直接调用我们封装后的SystemAlloc函数即 定长内存池中应该包含哪些成员变量 对于向堆申请到的大块内存我们可以用一个指针来对其进行管理但仅用一个指针肯定是不够的我们还需要用一个变量来记录这块内存的长度。 由于此后我们需要将这块内存进行切分为了方便切分操作指向这块内存的指针最好是字符指针因为指针的类型决定了指针向前或向后走一步有多大距离对于字符指针来说当我们需要向后移动n个字节时直接对字符指针进行加n操作即可。 其次释放回来的定长内存块也需要被管理我们可以将这些释放回来的定长内存块链接成一个链表这里我们将管理释放回来的内存块的链表叫做自由链表为了能找到这个自由链表我们还需要一个指向自由链表的指针。 因此定长内存池当中包含三个成员变量 _memory指向大块内存的指针。 _remainBytes大块内存切分过程中剩余字节数。 _freeList还回来过程中链接的自由链表的头指针。 内存池如何管理释放的对象 对于还回来的定长内存块我们可以用自由链表将其链接起来但我们并不需要为其专门定义链式结构我们可以让内存块的前4个字节32位平台或8个字节64位平台作为指针存储后面内存块的起始地址即可。 因此在向自由链表插入被释放的内存块时先让该内存块的前4个字节或8个字节存储自由链表中第一个内存块的地址然后再让_freeList指向该内存块即可也就是一个简单的链表头插操作。 如何让一个指针在32位平台下解引用后能向后访问4个字节在64位平台下解引用后能向后访问8个字节 首先我们得知道32位平台下指针的大小是4个字节64位平台下指针的大小是8个字节。而指针指向数据的类型决定了指针解引用后能向后访问的空间大小因此我们这里需要的是一个指向指针的指针这里使用二级指针就行了。 当我们需要访问一个内存块的前4/8个字节时我们就可以先该内存块的地址先强转为二级指针由于二级指针存储的是一级指针的地址二级指针解引用能向后访问一个指针的大小因此在32位平台下访问的就是4个字节在64位平台下访问的就是8个字节此时我们访问到了该内存块的前4/8个字节。 void* NextObj(void* ptr) {return (*(void**)ptr); } 需要注意的是在释放对象时我们应该显示调用该对象的析构函数清理该对象因为该对象可能还管理着其他某些资源如果不对其进行清理那么这些资源将无法被释放就会导致内存泄漏。 //释放对象 void Delete(T* obj) {//显示调用T的析构函数清理对象obj-~T();//将释放的对象头插到自由链表NextObj(obj) _freeList;_freeList obj; } 内存池如何为我们申请对象 当我们申请对象时内存池应该优先把还回来的内存块对象再次重复利用因此如果自由链表当中有内存块的话就直接从自由链表头删一个内存块进行返回即可。 如果自由链表当中没有内存块那么我们就在大块内存中切出定长的内存块进行返回当内存块切出后及时更新_memory指针的指向以及_remainBytes的值即可。 需要特别注意的是由于当内存块释放时我们需要将内存块链接到自由链表当中因此我们必须保证切出来的对象至少能够存储得下一个地址所以当对象的大小小于当前所在平台指针的大小时需要按指针的大小进行内存块的切分。 此外当大块内存已经不足以切分出一个对象时我们就应该调用我们封装的SystemAlloc函数再次向堆申请一块内存空间此时也要注意及时更新_memory指针的指向以及_remainBytes的值。 //申请对象 T* New() {T* obj nullptr;//优先把还回来的内存块对象再次重复利用if (_freeList ! nullptr){//从自由链表头删一个对象obj (T*)_freeList;_freeList NextObj(_freeList);}else{//保证对象能够存储得下地址size_t objSize sizeof(T) sizeof(void*) ? sizeof(void*) : sizeof(T);//剩余内存不够一个对象大小时则重新开大块空间if (_remainBytes objSize){_remainBytes 128 * 1024;_memory (char*)SystemAlloc(_remainBytes 13);if (_memory nullptr){throw std::bad_alloc();}}//从大块内存中切出objSize字节的内存obj (T*)_memory;_memory objSize;_remainBytes - objSize;}//定位new显示调用T的构造函数初始化new(obj)T;return obj; } 需要注意的是与释放对象时需要显示调用该对象的析构函数一样当内存块切分出来后我们也应该使用定位new显示调用该对象的构造函数对其进行初始化。 4. 定长内存池代码 // // ObjectPool.hpp // ObjectPool // // Created by 卜绎皓 on 2023/1/28. //#include iostream #include vector #include time.h using std::cout; using std::endl;//定长内存池 templateclass T class ObjectPool { public://申请对象T* New(){T* obj nullptr;//优先把还回来的内存对象重复利用if(_freeList ! nullptr){//从自由链表删除一个对象void* next *((void**)_freeList);obj (T*)_freeList;_freeList next;}else{//保证对象能够储存下地址size_t objSize sizeof(T) sizeof(void*) ? sizeof(void*) : sizeof(T);//剩余内存不够一个对象大小时则重新开大空间if(_remainBytes objSize){_remainBytes 128 * 1024;_memory (char*)malloc(_remainBytes);if(_memory nullptr)throw std::bad_alloc();}//从大块内存中切除objSize字节的内容obj (T*)_memory;_memory objSize;_remainBytes - objSize;}//定位new显示调用T的构造函数初始化new(obj) T;return obj;}//释放对象void Delete(T* obj){//显示调用T的析构函数清理对象obj-~T();//将释放的对象头插到自由链表*(void**)obj _freeList;_freeList obj;}private:char* _memory nullptr; // 指向大块内存的指针size_t _remainBytes 0; // 大块内存切分剩余的字节数void* _freeList nullptr; // 还回来过程中链接的自由链表的头指针 }; 5. 性能测试 struct TreeNode {int _val;TreeNode* _left;TreeNode* _right;TreeNode():_val(0), _left(nullptr), _right(nullptr){} };void TestObjectPool() {// 申请释放的轮次const size_t Rounds 3;// 每轮申请释放多少次const size_t N 1000000;std::vectorTreeNode* v1;v1.reserve(N);//malloc和freesize_t begin1 clock();for (size_t j 0; j Rounds; j){for (int i 0; i N; i){v1.push_back(new TreeNode);}for (int i 0; i N; i){delete v1[i];}v1.clear();}size_t end1 clock();//定长内存池ObjectPoolTreeNode TNPool;std::vectorTreeNode* v2;v2.reserve(N);size_t begin2 clock();for (size_t j 0; j Rounds; j){for (int i 0; i N; i){v2.push_back(TNPool.New());}for (int i 0; i N; i){TNPool.Delete(v2[i]);}v2.clear();}size_t end2 clock();cout new cost time: end1 - begin1 endl;cout object pool cost time: end2 - begin2 endl; } 在代码中我们先用new申请若干个TreeNode对象然后再用delete将这些对象再释放通过clock函数得到整个过程消耗的时间。new和delete底层就是封装的malloc和free 然后再重复该过程只不过将其中的new和delete替换为定长内存池当中的New和Delete此时再通过clock函数得到该过程消耗的时间。 可以看到在这个过程中定长内存池消耗的时间比malloc/free消耗的时间要短。这就是因为malloc是一个通用的内存池而定长内存池是专门针对申请定长对象而设计的因此在这种特殊场景下定长内存池的效率更高正所谓“尺有所短寸有所长”。 文章转载自: http://www.morning.ryjl.cn.gov.cn.ryjl.cn http://www.morning.wrlqr.cn.gov.cn.wrlqr.cn http://www.morning.brkc.cn.gov.cn.brkc.cn http://www.morning.nkdmd.cn.gov.cn.nkdmd.cn http://www.morning.jppdk.cn.gov.cn.jppdk.cn http://www.morning.ygbq.cn.gov.cn.ygbq.cn http://www.morning.ypqwm.cn.gov.cn.ypqwm.cn http://www.morning.jxpwr.cn.gov.cn.jxpwr.cn http://www.morning.wrtsm.cn.gov.cn.wrtsm.cn http://www.morning.kyfnh.cn.gov.cn.kyfnh.cn http://www.morning.csxlm.cn.gov.cn.csxlm.cn http://www.morning.fnssm.cn.gov.cn.fnssm.cn http://www.morning.sfnjr.cn.gov.cn.sfnjr.cn http://www.morning.wfqcs.cn.gov.cn.wfqcs.cn http://www.morning.zwhtr.cn.gov.cn.zwhtr.cn http://www.morning.fkyrk.cn.gov.cn.fkyrk.cn http://www.morning.dkfrd.cn.gov.cn.dkfrd.cn http://www.morning.knsmh.cn.gov.cn.knsmh.cn http://www.morning.ndhxn.cn.gov.cn.ndhxn.cn http://www.morning.lmqw.cn.gov.cn.lmqw.cn http://www.morning.tfzjl.cn.gov.cn.tfzjl.cn http://www.morning.qnbzs.cn.gov.cn.qnbzs.cn http://www.morning.mdtfh.cn.gov.cn.mdtfh.cn http://www.morning.homayy.com.gov.cn.homayy.com http://www.morning.dpdns.cn.gov.cn.dpdns.cn http://www.morning.jwcmq.cn.gov.cn.jwcmq.cn http://www.morning.rksnk.cn.gov.cn.rksnk.cn http://www.morning.dtmjn.cn.gov.cn.dtmjn.cn http://www.morning.lxqyf.cn.gov.cn.lxqyf.cn http://www.morning.cjsrg.cn.gov.cn.cjsrg.cn http://www.morning.ccyjt.cn.gov.cn.ccyjt.cn http://www.morning.xhlht.cn.gov.cn.xhlht.cn http://www.morning.dwtdn.cn.gov.cn.dwtdn.cn http://www.morning.nchsz.cn.gov.cn.nchsz.cn http://www.morning.pmysp.cn.gov.cn.pmysp.cn http://www.morning.qymqh.cn.gov.cn.qymqh.cn http://www.morning.tnbas.com.gov.cn.tnbas.com http://www.morning.xpmhs.cn.gov.cn.xpmhs.cn http://www.morning.ggrzk.cn.gov.cn.ggrzk.cn http://www.morning.rcmwl.cn.gov.cn.rcmwl.cn http://www.morning.qbkw.cn.gov.cn.qbkw.cn http://www.morning.grqlc.cn.gov.cn.grqlc.cn http://www.morning.mnlk.cn.gov.cn.mnlk.cn http://www.morning.gcysq.cn.gov.cn.gcysq.cn http://www.morning.wyzby.cn.gov.cn.wyzby.cn http://www.morning.qyqmj.cn.gov.cn.qyqmj.cn http://www.morning.qkcyk.cn.gov.cn.qkcyk.cn http://www.morning.yxyyp.cn.gov.cn.yxyyp.cn http://www.morning.znmwb.cn.gov.cn.znmwb.cn http://www.morning.dqxph.cn.gov.cn.dqxph.cn http://www.morning.bcdqf.cn.gov.cn.bcdqf.cn http://www.morning.mhdwp.cn.gov.cn.mhdwp.cn http://www.morning.zcwwb.cn.gov.cn.zcwwb.cn http://www.morning.nqwz.cn.gov.cn.nqwz.cn http://www.morning.hymmq.cn.gov.cn.hymmq.cn http://www.morning.hwprz.cn.gov.cn.hwprz.cn http://www.morning.cwqpl.cn.gov.cn.cwqpl.cn http://www.morning.lkwyr.cn.gov.cn.lkwyr.cn http://www.morning.bmssj.cn.gov.cn.bmssj.cn http://www.morning.ztfzm.cn.gov.cn.ztfzm.cn http://www.morning.ktlxk.cn.gov.cn.ktlxk.cn http://www.morning.sbyhj.cn.gov.cn.sbyhj.cn http://www.morning.khdw.cn.gov.cn.khdw.cn http://www.morning.kycwt.cn.gov.cn.kycwt.cn http://www.morning.qfplp.cn.gov.cn.qfplp.cn http://www.morning.pqkgb.cn.gov.cn.pqkgb.cn http://www.morning.ydfr.cn.gov.cn.ydfr.cn http://www.morning.rbmm.cn.gov.cn.rbmm.cn http://www.morning.lznfl.cn.gov.cn.lznfl.cn http://www.morning.fpjxs.cn.gov.cn.fpjxs.cn http://www.morning.rmyqj.cn.gov.cn.rmyqj.cn http://www.morning.wlqbr.cn.gov.cn.wlqbr.cn http://www.morning.spnky.cn.gov.cn.spnky.cn http://www.morning.kljhr.cn.gov.cn.kljhr.cn http://www.morning.mtktn.cn.gov.cn.mtktn.cn http://www.morning.gmrxh.cn.gov.cn.gmrxh.cn http://www.morning.rqmqr.cn.gov.cn.rqmqr.cn http://www.morning.bctr.cn.gov.cn.bctr.cn http://www.morning.yrpd.cn.gov.cn.yrpd.cn http://www.morning.lkbdy.cn.gov.cn.lkbdy.cn 查看全文 http://www.tj-hxxt.cn/news/260031.html 相关文章: 个人网站建设方案书实例中国住建厅网站官网 给网站加个地图的代码wordpress实现瀑布流 做网站实训报告营销网站搭建建议 城阳做网站的北京网站维护公司 微网站 demowordpress 反向代理 帝国音乐网站怎么做数据表西安高新区网站建设 浙江联科网站开发wordpress怎么播放视频 设计 网站 现状中山seo排名 网站建设期的网站案例海珠区建网站公司 做网站交接什么时需要交接企业展厅公司哪家好 建网站服务器怎么选择孝义网站开发 网站设计建设公司教程旅游网站建设论文 宝安网站设计师nginx 网站建设 河南怎样做网站推广公司网站开发哪家好 北京建网站多少钱注册100万公司需要多少钱 基于django的电子商务网站设计权威发布的图片 免费 个人网站网站开发项目可行性分析 网站开发 工具做网站赚钱 优帮云 wordpress博客模板安装失败seo综合排名优化 制作伪装网站自助服务系统网站 山东省建设部继续教育网站广州加盟网站建设 迅驰互联网站建设网络推广怎么样互联网设计是什么 招聘 网站开发西安网站建设交易 建设中心小学网站微信开发有哪些 常州网站建设段新浩安徽安庆旅游必去十大景点 php 判断 $_get 然后跳转到相印的网站手机网站用什么程序做 网站建设维护费 会计科目wordpress仿百度文库 大兴58网站起名网站制作南宁网站建设哪家公司好 比较好的室内设计网站wordpress 数据库文件 互助网站制作公司数据库网站 建设方案