
C/C++
文章平均质量分 87
DeepClick
分享ClickHouse技术解决方案和最佳实践。
展开
-
内存泄漏专题(9)内存池陷阱
如上所示,我们每次都从父池子里申请一个子池子,然后使用完成后,调用apr_pool_destroy将子池子的内存归还给父池子,这样,只要每一轮调用中,没有特别出格的内存调用,父池子的大小会保持在一个相对稳定的大小,而不会无线扩张。我们在程序一开始申请了一个内存池,然后进入mainloop进行业务处理,这个mainloop通常是不会退出的,只有当接收到了退出信号的时候,才会退出,在退出的时候,会销毁内存池。理论上来说,内存池应该是非常安全的才对,我又为什么说内存池会有内存泄漏的陷阱呢?原创 2023-07-26 16:41:43 · 351 阅读 · 0 评论 -
内存泄漏专题(8)hook之C++运算符重载
类,该类用来存储内存信息,包括内存的地址,大小。如果愿意的话,还可以存储调用的位置,这里为了简化处理,就不演示了。的内存管理是交由编译器处理的,虽然程序员无需手动管理,但实际上也调用了。中是否还有没有元素存在,就知道还有没有内存泄漏了。是智能指针,其内存的生命周期由编译器进行管理,无需手动释放,在。因此,该段代码有两处内存泄漏,分别为指针。函数结束后才会进行,因此,我们只需要在析构函数中判断一下,可以看到,确实打印出了两处内存泄漏,第一处是。的内存只有申请,没有释放,对象只有申请,没有释放,原创 2023-07-26 15:31:48 · 443 阅读 · 0 评论 -
内存泄漏专题(7)hook之宏定义
在此之前,我们封装一个链表,用来存储每次申请内存的地址以及申请内存的大小,在每次申请内存的时候,向链表添加一条数据,每次释放的时候,将对应的记录删除掉,那么,当程序结束,如果链表还有数据,那就是没有释放的泄露部分的内存。我们注意在第1行包含了头文件,并在第4行和14行分别调用了mcheck的接口,这样的话,就可以检测出这个过程中出现的内存泄露问题,以上代码运行会产生一个名为。它告诉我们第6,11,13行分别出现了内存泄露,大小是多少,调用的那么函数申请的内存,还是比较详细的。函数时,先调用我们自己定义的。原创 2023-07-26 15:29:53 · 564 阅读 · 0 评论 -
内存泄漏专题(6)AIX系统内存泄漏调试浅探
AIX系统作为IBM公司PowerPC架构的一款比较典型的操作系统,虽然随着Linux的免费开源的普及,市面上几乎很少见,但仍然广泛存在于政府、银行、证券等核心系统中。由于该系统闭源,很多调试手段都无法在AIX上有效运用,比如mtracebccvalgrind等,空有神力,却无法为之臂助。好在IBM自己提供了一套内存泄漏的调试工具,可以比较方便的定位与调试。当然,要想排查内存泄漏,首先我们得确认程序有没有内存泄漏。你可以使用诸如nmon之类的监控工具持续观察某个程序内存的使用情况,看它有没有持续上涨。原创 2023-07-03 16:58:39 · 761 阅读 · 0 评论 -
内存泄露专题(5)动态内存追踪大杀器:bcc
eBPF这几年网上炒得很热,甚至于有许多开发者十分迷信该技术,虽然eBPF的确能解决不少问题,但这种技术是否能真正用于生产环境,其实是需要根据场景而异的。这里就不做过多的篇幅来讲述eBPF的概念了,感兴趣的可以上网自己查找相关资料。bcc是一个eBPF的工具集,使用C/C++实现,外层使用python进行封装。由于eBPF需要以上才能够支持,因此,如果你的服务器是CentOS7或者比较低版本的Ubuntu,都是无法使用该工具的。笔者所使用的的服务器是CentOS7.9,内核版本为3.10.0。原创 2023-06-28 08:05:31 · 1246 阅读 · 0 评论 -
内存泄露专题(4)mtrace内存追踪
等内存申请释放的调用处,插入自己的一些代码,用来记录内存的信息,包括指针的地址,内存块的大小等。的内存信息,其中包含有内存申请的地址,内存申请的大小,释放内存的地址,释放内存的大小。内存并没有释放,所以这段程序是会内存泄漏的。行,它告诉我们下面这些内存是没有被释放的,其次可以看到从第。系统内核自带的一个内存追踪的函数,它会在每个内存申请函数。工具集中的一个,所以如果系统没有该命令的话,可以使用。的位置记录下信息,并在每个内存释放的位置记录下。函数取消内存使用记录。大小的内存没有被释放,这个大小,转成。原创 2023-06-28 08:03:40 · 2510 阅读 · 0 评论 -
内存泄漏专题(3)内存泄漏调试神器valgrind
追踪内存泄漏的工具有很多,网上一搜能找到一大片,但针对不同的系统,均有不同的玩法,且有些东西,如果不是实际实战一把,真到了用的时候,仍然会眼高手低,不知如何下手。上一章中,我们提出了排查内存泄漏是否存在的几种思路,但只是停留在理论上,本章就这几种思路提供具体的解决方案。在本章节,将以具体的例子的方式来演示如何定位内存泄漏的具体位置。的初学者对该工具都不陌生,很多内存检测的入门教程都会提到该工具。对于内存泄漏的定位还是非常准确的,因此不失为一个内存泄漏调试的好手段。行则报告了内存泄漏的信息,说有一次。原创 2023-06-28 07:59:57 · 609 阅读 · 0 评论 -
内存泄漏专题(2)如何判断程序有内存泄露
当内存池化之后,由于对于内存的申请和销毁都是先由内存池初始化时向系统申请一块内存,在程序结束时销毁该内存池,中间所有关于内存的操作都是针对池子而言的,因此不太容易出现内存泄漏。如果某个程序是长期运行的,那么可能申请的内存一直存在于池子中,不会得到销毁,定长内存池相对好一点 ,特别是对于非定长的内存池,如果在程序中一味地从池子中申请内存,但并没有在适当的地方及时归还给池子,同样会造成内存越用越大,导致系统内存耗尽。这时候,我们可能要借助一些其他的调试手段或者第三方工具,来判断是否有内存泄漏,比如著名的。原创 2023-06-28 07:57:32 · 496 阅读 · 0 评论 -
内存泄露专题(1)何为内存泄露
只有对那些占用内存比较小的变量,对执行效率要求比较高的地方,可能直接使用栈上的内容,对于一些比较占用内存的结构,比如结构体、字符串等,通常的做法,都是在堆上申请内存。所谓内存泄漏,就是由于程序主动申请了内存,但是又没有主动释放它,那么这块内存可能就会一直驻留在进程中,只要进程不结束,内存就一直不释放。类的守护进程,一旦发生内存泄漏,那么后果是不可设想,因为在长时间的运行过程中,进程一点点蚕食系统内存,最终可能导致系统内存耗尽,从而导致系统崩溃。诞生的那一天起,内存和指针就好比天上的两朵乌云,笼罩在无数。原创 2023-06-28 07:53:52 · 201 阅读 · 0 评论 -
C语言获取服务器MAC地址
在Linux系统,可以通过系统调用函数ioctl很容易就获取到服务器的mac地址。它的信息保存在结构体中,有可能不止一个。获取到的信息保存在ifc_buf中。通过上面简单的两步,就能获取到Linux服务器上所有的网卡对应的mac地址。可见,取出来的mac地址是正确的。原创 2023-06-25 07:45:17 · 1245 阅读 · 0 评论 -
wtmp日志读取
之前遇到一个AIX服务器登录不上,但是能ping通的事情。一开始我怀疑是sshd服务坏掉了,但是使用telnet也无法登录。好在这台机器所在的机房就在我隔壁,于是外接显示器,直接上机操作。好在直接通过物理介质还是能登录得上去的。上去一看,好家伙,直接提示根目录磁盘不足了。于是就查跟目录下都有哪些东西占用了比较大的空间。不看不知道,一看吓一跳,根目录下一共3.2G/var/log下一个wtmp文件就占了2.8G。那么这个wtmp是啥?能不能删除呢?查了一下资料,才知道这个wtmp。原创 2023-06-16 18:48:37 · 3474 阅读 · 0 评论 -
C语言柔性数组
所谓柔性数组,是C语言中的一个概念,也叫零长数组。顾名思义,这个数组的长度是不固定的,当没有值时,它的sizeof长度为0。上面的结构体中的char buf[]就是一个柔型数组。那么,怎样才算满足一个柔型数组的定义呢?原创 2023-06-15 09:21:13 · 1106 阅读 · 0 评论 -
AIX5.3安装Python3遇到的坑
最近在折腾AIX5.3,这是一款非常古老的power架构的服务器,目前IBM官方已经不维护,但是仍然在很多银行里跑着比较核心的业务,由于我们的客户大部分是面向银行,少不了要做AIX5.3上的应用软件适配。本文记录在AIX5.3上编译安装Python3时遇到的一些坑。由于AIX5.3非常古老,基本上很难找得到可以用的Python3安装包,只能通过源码编译的方式进行编译。在此之前,需要安装好gcc编译器。安装过程不表(坑也比较多,但都是rpm安装,这里就不详细展开了),我安装的gcc版本是4.8.4。原创 2023-06-07 11:44:39 · 828 阅读 · 0 评论 -
C语言获取Linux单网卡的多IP地址
上一篇文章主要讲了AIX系统下的单网卡多IP的IP的配置以及C语言获取的方法。相比AIX,Linux下配置就方便得多。首先找到我们需要配置的网卡名,比如p2p2, 进入到目录,找到ifcgf-p2p2如上图,我们增加了两个IP, 一个为,一个为。完成后,从ifcofig但是用ip a。原创 2023-05-31 13:46:07 · 1313 阅读 · 0 评论 -
C语言获取AIX单网卡的多IP地址
在AIX上,可以使用命令给单个网卡配置多个IP别名。en1IPNETMASKF10查看网卡信息,已经配置完成。原创 2023-05-30 18:46:33 · 1101 阅读 · 0 评论 -
性能媲美epoll的io_uring
io_uring通过队列将send和recv的数据做到异步解耦,从而提升了性能,但是相比于epollio_uring过分依赖于内核版本(kerner5.10以上),且操作相对比较繁琐。因此,现阶段可以作为了解,主流使用应该还是以epoll为主。C/C++Linux服务器开发/高级架构师。原创 2023-05-23 07:51:42 · 782 阅读 · 0 评论 -
GDB调试无行号,报dwarf error问题解决
的问题,网上很多资料说得很含糊,大多也都一知半解,真要深入研究,还是有很多坑的。一般出现在gcc编译环境版本与gdb调试环境版本不匹配导致,一般可以通过编译时指定dwarf版本解决除了我们自身的源码需要指定dwarf版本,程序所依赖的第三方库也需要使用指定的dwarf版本进行编译推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,原创 2023-05-20 08:28:54 · 8352 阅读 · 6 评论 -
实战TCP三次握手
在几乎所有的后端开发面试题中,TCP三次握手绝对是最被面试官青睐的题目之一。但是这个东西,平时开发中看不见,摸不着,对于很多人来说,是纯理论的知识,玄之又玄。但是为了应对面试,又不得不去死记硬背。就……真的是硬背。我之前面试过一个小哥,问了一嘴三次握手,这小哥掰着手指头搁那背,ACK和SEQ都搞反了,我问他SYN标志代表什么意思,也说不大清楚。所以是不是真的搞懂了,一问便知。原创 2023-05-20 07:49:02 · 2173 阅读 · 1 评论 -
深入浅出字符编码
else {} }要问为什么是这段代码?我们往往也能说得出:因为大小写字母在ASCII码上正好相差32(字符'a'为97, 字符'A'为65)。我们在进行字符初始化的时候,往往会将字符初始化为'\0'。因为'\0'在ASCII码中对应的数值是0。我们理所应当地知道char型字符对应的范围是0~127,因为ASCII码的范围就是0~127。但是有没有想过,为什么是ASCII码?所谓的ASCII码,又到底是什么?要说起ASCII码,不得不说起编码格式。原创 2023-05-08 07:51:35 · 478 阅读 · 0 评论 -
7种常见网络并发模型介绍
对于网络服务器后端开发,为满足不同并发场景的需要,一般来说,不外乎几种常见的并发模型,除了一些教学场景常用的单线程、多进程(线程)的服务器实现外,生产用的服务器,一般都会考虑使用IO多路复用模型。而常见的IO多路复用场景 ,可以设计得很简单,也可以设计得比较复杂,一般根据业务需要而定。本文总结了一些比较常见的服务器并发模型,基本涵盖了 大部分业务场景。在实际业务开发的技术选型时,可根据场景,选取一款稳定、可靠的网络模型,还是十分关键的。原创 2023-05-08 07:42:53 · 1858 阅读 · 0 评论 -
一文说透IO多路复用select/poll/epoll
如果我们要开发一个高并发的TCP程序。常规的做法是:多进程或者多线程。即:使用其中一个线程或者进程去监听有没有客户端连接上来,一旦有新客户端连接,就新开一个线程(进程),将其扔到线程(或进程)中去处理具体的读写操作等业务逻辑,主线程(进程)继续等待,监听其他的客户端。这样操作往往存在很大的弊端。首先是浪费资源,要知道,单个进程的最大虚拟内存是4G,单个线程的虚拟内存也有将近8M,那么,如果上万个客户端连接上来,服务器将会承受不住。其次是浪费时间,因为你必须一直等在accept那个地方,十分被动。原创 2023-05-07 09:36:33 · 768 阅读 · 0 评论 -
指针函数和函数指针
概述指针函数和函数指针是C语言里两个比较绕的概念。但是不仅面试题爱考,实际应用中也比较广泛。很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针、函数指针变量、函数指针数组放在一块的时候,能把强迫症的人活活逼疯。其实如果理解了这些概念的本质,是不需要死记硬背的,理解起来也比较容易。指针函数指针函数: 顾名思义,它的本质是一个函数...原创 2019-03-30 16:21:36 · 129784 阅读 · 89 评论 -
魔性的float浮点数精度问题
从一个问题引入如果你以前接触过C语言,那么对下面的这段代码一定很熟悉:#include <stdio.h>int main(void){ float f_num1 = 21.75; float f_num2 = 13.45; printf("f_num1 = %f\n", f_num1); printf("f_n...原创 2019-09-18 15:27:42 · 583 阅读 · 0 评论 -
C语言各种变量的初始化
数值类变量初始化整型、浮点型的变量可以在定义的同时进行初始化,一般都初始化为0。 int inum = 0; float fnum = 0.00f; double dnum = 0.00;字符型变量初始化字符型变量也可在定义的同时进行初始化,一般初始化为'\0'。char ch = '\0'; 字符串初始化字符串初始化的方法比较多,我这里简单介绍三种...原创 2018-10-07 23:19:00 · 29750 阅读 · 1 评论