core文件路径:
/proc/sys/kernel/core_pattern
更改Core文件的地址:echo “/corefile/core-%e-%p-%t” > core_pattern
gdb命令:info singal info sybmol up:将栈帧向上回溯一层
调试器的bt的地址来自进程上的栈,根据栈里保存的函数返回地址来显示的。
https://pan.baidu.com/s/1kF1NDrGpu9wTUUDGAliCIA
TCP笔记:
如果我们确实想在某个TCP链接上发送一个FIN, 那么可以改用shutdown函数,代替close, 我们还得清楚, 如果父进程对每个由Accept返回的已连接套接字都不调用close, 那么并发服务器中将会发送什么,
首先, 父进程最终将耗尽可用描述符, 因为任何进程在任何时刻刻拥有的打开着的描述符通常都是有限的, 不过更重要的是,没有一个客户连接会被终止, 子进程关闭已连接套接字时, 它的引用计数将由2减为1,
且保持1,因为父进程永不关闭任何已连接套接字,这将妨碍TCP连接终止序列的发生, 导致连接一直打开着。
TIME_WAIT状态:是主动断开连接方的状态。
TCP的TIME_WAIT状态是网络编程人员不容易理解的概念, 存在这一状态是为了实现完整地终止全双工的连接(即处理最终的ACK丢失的情形),并允许老的重复分解从网络中消失。
TCP的流量控制:
TCP总是告诉对方它能够接受多少字节的数据,这称为通告窗口,任何时刻,这个窗口指出接收缓冲区的可用空间,从而确保发送方
发送的数据不会溢出接收缓冲区,窗口时刻动态地变化:当接收到发送发的数据时,窗口大小减小,而当接收方应用进程从缓冲区中读取
数据时,窗口大小增大,窗口的大小减小到0是有可能的:TCP的接收缓冲区满,它必须等待应用进程从这个缓冲区读取数据后才能再接收
从发送方来的数据。
TCP窗口大小:是指无需等待确认应答而可以继续发送数据的最大值(指数据大小)
mount -t cifs //10.14.64.32/Code/trunk /mnt/Code/trunk -o username=yuyixiong,password=xxxxx!,vers=2.0
使用:mount //10.14.64.101/Code/trunk /mnt/yuyixiong -o username=yuyixiong,password=xxxxx!
取消:umount /mnt/Code/trunk
拷贝构造函数:
CExample(const CExample& C), 是否开辟新资源来区分是深拷贝还是浅拷贝
模式:
实际上 Prototype 模式和 Builder 模式、AbstractFactory 模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),
它们之间的区别是:Builder 模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory 模式重在产生多个相互依赖类的对象,
而 Prototype 模式重在从自身复制自己创建新类。
几个常用的寄存器
sp/esp/rsp(16bit/32bit/64bit)栈寄存器—指向栈顶
bp/ebp/rbp 栈基址寄存器—指向栈底
ip/eip/rip 程序指令寄存器—指向下一条待执行指令
指令寄存器 EIP
EIP —— 标志当前进程将要执行指令位置,在64位模式下扩展为 RIP 64位指令寄存器。
通用寄存器
32位通用寄存器有八个,eax, ebx, ecx, edx, esi, edi, ebp, esp,
他们主要用作逻辑运算、地址计算和内存指针,具体功能如下:
eax 累加和结果寄存器
ebx 数据指针寄存器
ecx 循环计数器
edx i/o指针
esi 源地址寄存器
edi 目的地址寄存器
esp 堆栈指针
ebp 栈指针寄存器
在 64-bit 模式下,有16个通用寄存器,但是这16个寄存器是兼容32位模式的,
32位方式下寄存器名分别为 eax, ebx, ecx, edx, edi, esi, ebp, esp, r8d – r15d.
在64位模式下,他们被扩展为 rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp, r8 – r15.
其中 r8 – r15 这八个寄存器是64-bit模式下新加入的寄存器。
寄存器简介
先明确一点,本文关注的是通用寄存器(后简称寄存器)。既然是通用的,使用并没有限制;后面介绍寄存器使用规则或者惯例,只是GCC(G++)遵守的规则。因为我们想对GCC编译的C(C++)程序进行分析,所以了解这些规则就很有帮助。
在体系结构教科书中,寄存器通常被说成寄存器文件,其实就是CPU上的一块存储区域,不过更喜欢使用标识符来表示,而不是地址而已。
X86-64中,所有寄存器都是64位,相对32位的x86来说,标识符发生了变化,比如:从原来的%ebp变成了%rbp。为了向后兼容性,%ebp依然可以使用,不过指向了%rbp的低32位。
X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。
刚刚说到,寄存器集成在CPU上,存取速度比存储器快好几个数量级,寄存器多了,GCC就可以更多的使用寄存器,替换之前的存储器堆栈使用,从而大大提升性能。
让寄存器为己所用,就得了解它们的用途,这些用途都涉及函数调用,X86-64有16个64位寄存器,分别是:%rax,%rbx,%rcx,%rdx,%esi,%edi,%rbp,%rsp,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15。其中:
%rax 作为函数返回值使用。
%rsp 栈指针寄存器,指向栈顶
%rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
%rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
%r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值
性能:
Windows:
性能监视器:
开始=>输入"perfmon.msc" 或者 开始=>控制面板=>管理工具=>性能监视
资源监视器:
Windows任务管理器=>性能 标签=>资源监视器
boost::shared_ptr:
Boost文档说,在调用shared_from_this()之前,必须存在一个正常途径创建的shared_ptr
boost::shared_ptr spy(new Y)
boost::shared_ptr p = spy->GetSelf(); //OK
shared_from_this();
在enable_shared_from_this的成员函数 shared_from_this里,
内部存储的 weak_ptr 被转换为 shared_ptr, 从而增加了相应的引用计数,以确保相应的对象不会被删除
Windebug:
Specify the full name of the DLL to load: .reload /f D:\test\A.dll
set .exepath as described before eg: .exepath d:\test
set the image path and symbol path :.sympath d:\test
.dump /mf d:/test.dmp
读写锁在临界区最小时,开销最大。
数据锁:
struct bucket {
mutex mut;
NodeInfo* list;
}
许多数据结构都可以分割,数据结构的每个部分带有一把自己的锁,这样虽然每个部分一次只能执行一个临界区,但是数据结构的各个部分形成的临界区就可以并行执行了
, 在锁竞争必须降低时,和同步开销不是主要局限时,可以使用数据锁。 数据锁通过将一块过大的临界区分散到各个小的临界区来减少锁竞争。
避免死锁主要有三种方法:等级锁(给锁分等级(编号), 如果线程已经获取来编号相同或者更高的锁,就不允许再获取这把锁),条件锁(获取锁之前, try_lock一下),一次一把锁的设计.
软件包管理->软件安装->自定义安装->安装->确定
消除boost编译警告:
#ifndef _lint
#include “boost/shared_ptr.hpp”
#include “boost/make_shared.hpp”
#define Plugin_SharedPtr boost::shared_ptr
#endif
查看库是32还是64:
objdump -a *.a
objdump -a *.so
strings <可执行文件名>
getconf LONG_BIT 查看系统位数
根据进程名获取进程id:ps -ef | grep “name” | grep -v grep | awk ‘{print $2}’
pidstat -r -p 24427 1 5
ps aux|awk '{sum+=$6} END {print sum/1024}' :查看所有进程占用的内存情况
strace -o output.txt -T -tt -e trace=all -ff -p 27522:打印进程中各线程的接口调用情况
lstat,是一种文件描述词。意思是获取一些文件相关的信息。
内存调试:
pmap -xp pid Address: 内存开始地址
Kbytes: 占用内存的字节数(KB)
RSS: 保留内存的字节数(KB)
Dirty: 脏页的字节数(包括共享和私有的)(KB)
Mode: 内存的权限:read、write、execute、shared、private (写时复制)
Mapping: 占用内存的文件、或[anon](分配的内存)、或[stack](堆栈)
Offset: 文件偏移
Device: 设备名 (major:minor)
linux:
lsof -p 24921| wc -l
scp指定端口
scp xxx.so root@10.19.146.131:/opt//datasrc/
GDB:
(gdb) set height 0
(gdb) set logging on
valgrind 及 安装valgrind:
valgrind --tool=massif --log-file=./massif.log ./xxx
valgrind --error-limit=no --tool=memcheck --log-file=./valgrind.log --max-threads=1000 --leak-check=full --show-leak-kinds=all --show-mismatched-frees=yes ./xxx
//--leak-check=full --show-leak-kinds=all
安装:
1:rpm -ivh valgrind-3.13.0-13.el7.x86_64.rpm (建议该种方式)
2: vim /etc/yum.repos.d/CentOS-Base.repo 中把mirror.centos.org替换成192.0.0.56
/mirror.centos.org
192.0.0.56
vim /etc/yum.repos.d/CentOS-Base.repo
yum install valgrind
mallopt(M_TRIM_THRESHOLD,0):
Modifying M_TRIM_THRESHOLD is a trade-off between increasing
the number of system calls (when the parameter is set low) and
wasting unused memory at the top of the heap (when the
parameter is set high).
内存笔记:
库的文本段可能与其它使用相同库的进程共享, 它们各自有一份数据段的私有副本.
栈为线程栈.
sar -B 检查pgscan 寻找连续的页扫描(超过10秒), 它是内存压力的预兆
vmstat:检查si, so 列, 如果一直非0, 那么系统正存在内存压力. 指交换匿名换页, 每秒运行vmstat检查free列的可用内存. 单位KB, swpd:交换出的内存量, free:空闲的可用内存, buff:用于缓冲缓存的内存, cache:用于页缓存的内存.
dmesg 过滤Out of message ,是否有OOM终结者
slabtop:内核块分配统计信息
DTrace:分配跟踪
环境扩容:
1, yum install -y parted 将parted更新到parted-3.1-29.el7.x86_64
2,umount /opt/
3, umount /boot/efi
4, parted /dev/vda
resizepart 4 190GB (根据实际情况输入硬盘大小)
resizepart 6 190GB
quit
退出parted交互模式
5,pvresize --setphysicalvolumesize 173GB /dev/vda6
设置pv大小
6,lvresize -L +136GB /dev/opt /dev/vda6
7,mount /dev/opt /opt
8, xfs_growfs /opt
Close_WAIT:
产生原因:通过图上,我们来分析,什么情况下,连接处于CLOSE_WAIT状态呢?
在被动关闭连接情况下,在已经接收到FIN,但是还没有发送自己的FIN的时刻,连接处于CLOSE_WAIT状态。
通常来讲,CLOSE_WAIT状态的持续时间应该很短,正如SYN_RCVD状态。但是在一些特殊情况下,就会出现连接长时间处于CLOSE_WAIT状态的情况。
出现大量close_wait的现象,主要原因是某种情况下对方关闭了socket链接,但是我方忙与读或者写,没有关闭连接。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不是AGAIN,就断开连接。
wc -l /proc/net/tcp 命令检查tcp 连接数
显示出传输和发送的网络吞吐量:
sar -n DEV 1 |awk ‘NR == 3 || $3 == “eth0”’
查看库的命令:
nm -D/U *.so
ldd -r *.so
objdump -D *.so
查看leveldb:
The mem
value shows how many files are mmap’ed, and the fd
value shows you
many file descriptors these files are using. You should check that fd
is a
small number (usually 0 on 64-bit hosts)
lsof -p $(pidof xxx) | awk 'BEGIN { fd=0; mem=0; } /ldb$/ { if ($4 == "mem") mem++; else fd++ } END { printf "mem = %s, fd = %s\n", mem, fd}'
查看动态库导出函数列表
1.使用objdump命令。
例如:objdump -tT xxx.so
2.使用nm命令(个人觉得使用nm方式查看更方便。)
例如 nm -D xxx.so
linux 指令:
ps -aux | grep $(pidof xxx) | grep “xxx” | awk ‘NR1{print “”$3"%"}’
top -n 1 -p $(pidof xxx)|grep xxx | awk 'NR1{print $9}’
递归锁: 单线程递归, 多线程互斥!
boost智能指针
shared_ptr 中存有一个weak_ptr,而weak_ptr对象有两个指针:px 指向对象实体,而 pn.pi_ 则指向的是指针的计数对象
读写锁:
互斥原则:
读-读能共存,
读-写不能共存,
写-写不能共存。
查看网卡信息: ethtool eno1 , ifconfig
查看网络io: netstat -i -c(持续输出) netstat -s (总结输出)
此“兆”不同于彼“兆”
sar -n DEV 1 | awk ‘NR == 3 || $3 == “eno1”’
iftop -B -n -N -i ens2f3 显示端口显示MB(千兆实际只有128左右), -i 指定网卡, -N端口 -n显示ip
在正式解析千兆网卡之前,先谈谈很多人容易搞混淆的概念。不少用户都曾经有这样的疑惑,自己是百兆网卡,但是在局域网内最多也就不到10MB/s的传输速度;办个“4M宽带”,下载速度也只有400KB/s…… 其实,这是大家搞错了MB和Mb的概念。一般我们所说的千兆和百兆,它的单位都是Mbps,而传输速度我们一般则用MB/s来作为单位。实际上和硬盘的容量概念一样,B是指Byte,而b则是指bit,1B=8b。那么替换到网络中也是一样,普通的百兆网卡理论传输速度为100Mbps,实际上只有12.5MB/s,而千兆网卡的理论传输速度则为125MB/s。明白了这点,相信就没人真的以为千兆网卡传输能达到1GB/s的速度了。事实上,就目前的应用环境而言,在大多数情况下,百兆网卡已经足够了,而各位的宽带带宽只要按照运营商给出的数字再除以8,也基本上就是自己宽带能下载的极限速度了。
ifconfig enp2s0f0 |sed -n "1p" | awk -F" " '{print $2}'|grep RUNNING
Map想用自定义类型作为key
1:使用结构体作为key时, 重载<运算符
2:使用指针类型作为key,但是要提供比较函数
系统日志:
/var/log/messages
dmesg -T
IO:
iostat -d -x -k 1
iostat -dxkzt -p sda 1 指定磁盘
pidstat -d -p 49766 1 指定进程IO
pidstat -d 1 //显示所有进程占用磁盘io情况
kB_rd/s:每秒从磁盘读取的KB
kB_wr/s:每秒写入磁盘KB
kB_ccwr/s:任务取消的写入磁盘的KB。当任务截断脏的pagecache的时候会发生。
COMMAND:task的命令名
网络性能:
查看TCP参数命令: sysctl -a |grep tcp
查看两个队列: 半连接队列:tcp_max_syn_backlog = 4096, 已连接队列 net.core.somaxconn = 1024 sysctl -a |grep net.core.somaxconn
lsof 按照进程ID列出包括套接字细节在内的打开的文件
ss:套接字统计信息
iftop:按主机总结网络接口吞吐量
traceroute:查看到目的地的路由, 开源需要安装
ip : 网络接口统计信息
nicstat : 网络接口吞吐量和使用率
sar : 统计历史信息
netstat -I=eno2 1
nestat -s
ifconfig eno2:检测网卡错误, 丢弃, 超限统计信息.
查看服务的在系统中的最近异常及状态:
systemctl status xxxx
设计模式:
八大原则:依赖倒置原则, 开放封闭原则(对扩展开放对修改封闭), 单一职责原则, 里式替换原则, 接口隔离原则, 对象组合优于类继承, 封装变化点, 面向接口编程(IInterface)
重构法则: 静态->动态 , 早绑定->晚绑定, 继承->组合, 编译时依赖->运行时依赖, 紧耦合->松耦合(抽象出来, 或者增加适配, 代理, 中间层)
nm objdump :
objdump -tT
查看库依赖项:objdump -x xxx.so | grep “NEEDED”
nm -D
查看库中接口: nm -D libxxx.so| awk ‘{if($2==“T”){print $3}}’
AMQ管理网页:
浏览器输入http://192.168.25.128:8161/
点击Manage ActiveMQ broker,输入admin/admin进入管理页面
进入主页面:
使用gcore工具产生core文件而不杀死进程:
$ gcore pid (进程号)
gdb的generate-core-file命令
(gdb) generate-core-file
Saved corefile core.19388
(gdb) detach
gdb 调试工具dump出可疑内存:
gdb attach #先连接到进程中
gdb dump memory /path/dump.bin 0x0011 0x0021 # dump 出内存段的信息,具体要 dump 的内存段地址,可以借助之前pmap 排查的结果,以及 cat /proc//maps 中指示的地址段得出
strings /path/dump.bin | less # 查看内存内容, 相信你能从中发现一些不一样的东西
用户自定义信号值:
kill -10 12345 or kill -SIGUSR1 12345
会给test发送SIGUSR1 信号。
kill -12 12345 or kill -SIGUSR2 12345
会给test发送SIGUSR2 信号。
CPU:
uptime:检查负载平均数以确认CPU负载是随时间上升还是下降,负载平均数超过了CPU核数通常代表CPU饱和.(一分钟, 五分钟, 十五分钟)
vmstat 虚拟内存统计信息, eg: vmstat -w (-w看的更清楚些)1 其中最后几列打印了系统全局范围的CPU平均负载. r 第一列标识可运行线程总数.
[root@HikvisionOS logs]# vmstat
procs -----------memory---------- —swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
67 0 295680 616404 28 29359808 0 0 2 43 0 1 16 21 62 0 0
pidstat -u -p 167647 1
pidstat -u -t(显示各线程的cpu统计)-p 12617 1
mpstat -P ALL 1 //打印每个CPU的报告, 多处理统计信息工具 %usr %sys %idle 三者加起来100%, 其中如果%usr +%sys等于100%表明CPU负荷高
perf record -g ./xxx 形成CPU火焰图, 利用perf report -i perf.data查看调用链统计信息
CPU性能之Linux 的load average .
top命令,w命令,uptime等命令都可以查看系统负载
系统负载(System Load)是系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度(进程等待队列的长度)。
平均负载(Load Average)是一段时间内系统的平均负载,这个一段时间一般取1分钟、5分钟、15分钟。
查看系统cpu核数: cat /proc/cpuinfo |grep "cpu core"|wc -l
查看cpu线程数:cat /proc/cpuinfo | grep "processor" | wc -l
如何判断服务器是超负荷?
首先查看cpu的核数, 如果cpu的核数是16核, 那么cpu的满负载在16左右, 如果超过16则是超负载, 如果小于16*0.7就是低负载
load average表示:有多少进程在等待被CPU调度(进程等待队列的长度), 并不能反应cpu的利用率, 只是表明CPU负载情况.
PING:
ping -c 4 -s 1500 10.10.68.131
抽象:
抽象是从感性认识出发,通过分析和比较,抽出共同点,撤开差异性的内容和联系,通过综合得出简单的、基本的规定的过程。分析、比较和综合是抽象的基础,没有分析、比较和综合就找不到事物的异同,也不能区分事物的本质属性和非本质属性。在抽象过程中,分析、比较和综合相互作用、相互渗透,抽象的具体过程也千差万别,但都包括如下基本过程:分离、提纯、简略.
抽象指的是从纷繁复杂的事物中提炼本质的过程,是一个具体到概念的过程, 例如苹果、香蕉、生梨、葡萄、桃子等,它们共同的特性就是水果。得出水果概念的过程,就是一个抽象的过程。
我们在开发的过程中要保持一种敏锐的感觉,发现可能的变化并且封装起来,只提供一个精心定义的接口让外界调用。这样你在接口后面所做的任何变化,外边就不受影响了
总结了一下网上关于__cxa_pure_virtual出现的可能:
1:线程切换的时候, 一个清空了虚函数表,另外一个线程却正要用
2:构造函数调用虚函数也会出这个问题
3:垂悬指针也会出现这个现象,父类指针指向子类实例,子类被释放后,用父类指针调用
free -m :
可用内存;=free的内存+cached的内存+buffers的内存
数据库表文件会急剧增大:
update,insert,delete,统称dml, dml频繁,表文件就会急剧增大, 执行下:select query from pg_stat_activity where query like ‘%channel_src%’ 查看当前表channel_src有哪些操作.
画图软件:
draw.io
C++实际模型是, 1 :对于一般继承是扩充已有存在的虚函数表; 2: 对于虚继承添加一个虚函数表指针
1: 多重或单继承时,扩充第一个继承的基类的虚函数表, 将所有基类虚函数表中已经重载的虚函数替换成派生类的虚函数地址.
2:多重继承时, 继承了多少个基类, 派生类的对象模型中就有多少个虚函数表指针, 派生类自身定义的虚函数则在第一个基类的虚函数表中
常用的缓存淘汰策略有以下:
先进先出算法(FIFO)
Least Frequently Used(LFU)
淘汰一定时期内被访问次数最少的页面,以次数作为参考
Least Recently Used(LRU)
淘汰最长时间未被使用的页面,以时间作为参考
//https://www.cnblogs.com/zhangfengshi/p/11466263.html
RTSP (Real Time Streaming Protocol) 缺省端口:554 国标5060