敲黑板:不能为了解决一个问题,引发其他更多问题
strace会追踪程序运行时的整个生命周期, 输出每一个系统调用的名字、参数、返回值和执行所消耗的时间等,是高级运维和开发人员排查问题的杀手铜。https://www.cnblogs.com/fadewalk/p/10847068.html
strace -tt -f -e trace=file -p 8691 strace -f -p 4730 -T -tt -o /home/futi/strace_4730.log
strace -tt -f -e trace=network -p 8691
Process 8691 attached with 2 threads [pid 8691] 14:31:59.077383 accept(6, 0, NULL) = -1 EAGAIN (Resource temporarily unavailable)
-f Trace child processes as they are created by currently traced processes as a result of the fork(2), vfork(2) and clone(2) system calls.
而-e trace!=open表示跟踪除了open以外的其他调用
常见选项:
-e trace=[set] 只跟踪指定的系统调用
-e trace=file 只跟踪与文件操作有关的系统调用
-e trace=process 只跟踪与进程控制有关的系统调用
-e trace =network 只跟踪与网络有关的系统调用
-e trace=signal 只跟踪与系统信号有关的系统调用
-e trace=desc 只跟踪与文件描述符有关的系统调用
-e trace=ipc 只跟踪与进程通信有关的系统调用
-e abbrev=[set] 设定strace输出的系统调用的结果集
-e raw=[set] 将指定的系统调用的参数以十六进制显示
-e signal=[set] 指定跟踪的系统信号
-e read=[set] 输出从指定文件中读出的数据
-e write=[set] 输出写入到指定文件中的数据
-e trace=network
Trace all the network related system calls.
-e trace=signal
Trace all signal related system calls.
-e trace=ipc
Trace all IPC related system calls.
-e trace=desc
Trace all file descriptor related system calls.
-e trace=memory
Trace all memory mapping related system calls.
ptrace系统调用提供了一种方法来跟踪和控制进程的执行, 它可以读取和修改进程地址空间中的内容,包括寄存器的值。ptrace主要用于实现断点调试和跟踪系统调用
long ptrace(enum __ptrace_request request, pid_t pid, void *addr,void *data);
ptrace的四个参数的含义为:
https://blog.csdn.net/jasonchen_gbd/article/details/44044539
https://fillzero.github.io/tool/process-of-strace.html
how-does-strace-work 【ok】 https://blog.packagecloud.io/eng/2016/02/29/how-does-strace-work/
This blog post explains how strace works, internally. We’ll examine the ptrace system call, which strace relies on
This blog post explains how strace works, internally. We’ll examine the ptrace system call, which strace relies on
https://github.com/torvalds/linux/blob/v3.13/kernel/ptrace.c#L982-L984
How does ptrace work in Linux?【ok】
https://www.cnblogs.com/axiong/p/6184638.html
Why do shells call fork()?
gstack - print a stack trace of a running process
3 gdb 设置断点后,执行continue 降低 程序速度吗?
会的。
A traced process runs slowly.
由此可见,C++在new时的初始化的规律可能为:对
#include <iostream>
using namespace std;
class A
{
public:
int a;
A() : a(10){};
};
class B
{
public:
int a;
};
void test1()
{
A *pa = new A;
cout << pa->a << endl;
B *pb = new B();
cout << pb->a << endl;
}
void test2()
{
int *a = new int[1000];
for (int i = 0; i < 10000; i++)
{
a[i] = i + 1;
}
delete[] a;
int *b = new int[1000];
for (int i = 0; i < 10; i++)
{
cout << b[i] << endl;
}
}
void test3()
{
int *a = new int[1000];
for (int i = 0; i < 10; i++)
{
a[i] = i + 1;
}
delete[] a;
int *b = new int[1000]();
for (int i = 0; i < 10; i++)
{
cout << b[i] << endl;
}
}
int main()
{
// test1();
test2();
test3();
return 0;
}
new int[1000] 没有初岁化,没有分配空间
C++多重继承的构造执行顺序:
1.首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造;2.执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造;
3.执行成员对象的构造函数,多个成员对象的构造函数按照声明的顺序构造;
4.执行派生类自己的构造函数;
5.析构以与构造相反的顺序执行;
#include <cstring>
#include <iostream>
int main()
{
#define PAUSE(msg) std::cout << msg << std::endl; std::cin >> p
char p;
size_t size = 1024 * 1024 *100;
char *l = new char[size]; //分配:0 物理内存
char *l = new char[size](); //分配:100 物理内存
PAUSE("new ");
memset(l, 1, size / 2);
PAUSE("using half large"); //分配50M 物理内存
memset(l, 1, size);
PAUSE("using whole large"); //分配100M 物理内存
delete []l;
PAUSE("del");
return 0;
}
The malloc() function allocates size bytes and returns a pointer to the allocated memory. // The memory is not initialized.
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.rst. https://www.acm-sigsim-mskr.org/Courseware/Fujimoto/Slides/FujimotoSlides-15-MemoryManagement.pdf
用过c做项目的话,对malloc 应该会印象至深。特别是分配出来的内存,没做初始化,里面是未定义的数据,这种在 c 里面经常出bug。
举个例子,malloc 分配出来一个结构体,里面有个字段表示状态。这种程序猿直接拿来用就很坑,所以很多时候用calloc分配,或malloc分配出来然后memset 0
我在c++经典的单机模式里面看到过,new应该是两个步骤,分配内存空间和对象初始化。这两个步骤还不是原子操作。应该就是对应着分配内存和写入操作
https://mp.weixin.qq.com/s/Ytw_N5zeLH50ItdgAsv3nA
ss -lnt
tcp_max_syn_backlog 128 增大半连接队列;开启 tcp_syncookies 功能 减少 SYN+ACK 重传次数
开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接,在前面我们源码分析也可以看到这点,当开启了 syncookies 功能就不会丢弃连接。
syncookies 是这么做的:服务器根据当前状态计算出一个值,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功
2tcp_abort_on_overflow 共有两个值分别是 0 和 1,其分别表示:
0 :如果全连接队列满了,那么 server 扔掉 client 发过来的 ack ;1 :如果全连接队列满了,server 发送一个 reset 包给 client,表示废掉这个握手过程和这个连接;
tcp_abort_on_overflow 共有两个值分别是 0 和 1,其分别表示:
0 :如果全连接队列满了,那么 server 扔掉 client 发过来的 ack ;1 :如果全连接队列满了,server 发送一个 reset 包给 client,表示废掉这个握手过程和这个连接;
如果要想知道客户端连接不上服务端,是不是服务端 TCP 全连接队列满的原因,那么可以把 tcp_abort_on_overflow 设置为 1, 这时如果在客户端异常中可以看到很多 connection reset by peer 的错误,
那么就可以证明是由于服务端 TCP 全连接队列溢出的问题
如果要想知道客户端连接不上服务端,是不是服务端 TCP 全连接队列满的原因,那么可以把 tcp_abort_on_overflow 设置为 1,这时如果在客户端异常中可以看到很多 connection reset by peer 的错误,那么就可以证明是由于服务端 TCP 全连接队列溢出的问题。
通常情况下,应当把 tcp_abort_on_overflow 设置为 0,因为这样更有利于应对突发流量。
举个例子,当 TCP 全连接队列满导致服务器丢掉了 ACK,与此同时,客户端的连接状态却是 ESTABLISHED,进程就在建立好的连接上发送请求。只要服务器没有为请求回复 ACK,请求就会被多次重发。如果服务器上的进程只是短暂的繁忙造成 accept 队列满,那么当 TCP 全连接队列有空位时,再次接收到的请求报文由于含有 ACK,仍然会触发服务器端成功建立连接。
所以,tcp_abort_on_overflow 设为 0 可以提高连接建立的成功率,只有你非常肯定 TCP 全连接队列会长期溢出时,才能设置为 1 以尽快通知客户端。
CP 全连接队列最大值从 128 增大到 5000 后,服务端抗住了 3 万连接并发请求,也没有发生全连接队列溢出的现象了。
完整的架构图:
[root@realhost /]# cat /proc/meminfo
MemTotal: 688576 kB 总内存
MemFree: 153736 kB 空闲内存
MemAvailable: 339884 kB 可用内存
Buffers: 16 kB 给文件的缓冲大小
Cached: 267672 kB 高速缓冲存储器
SwapCached: 36 kB 被高速缓冲存储用的交换空间的大小
Active: 222900 kB 活跃使用中的高速缓冲存储器页面文件大小
Inactive: 123700 kB 不经常使用中的告诉缓冲存储器文件大小
Active(anon): 31800 kB 活跃的匿名内存(进程中堆上分配的内存,是用malloc分配的内存)
Inactive(anon): 57272 kB 不活跃的匿名内存
Active(file): 191100 kB 活跃的file内存,//file内存:磁盘高速缓存的内存空间和“文件映射(将物理磁盘上的文件内容与用户进程的逻辑地址直接关联)”的内存空间,其中的内容与物理磁盘上的文件相对应
Inactive(file): 66428 kB 不活跃的file内存
Unevictable: 0 kB 不能被释放的内存页
Mlocked: 0 kB mlock()系统调用锁定的内存大小
SwapTotal: 2097148 kB 交换空间总大小
SwapFree: 2096884 kB 空闲交换空间
Dirty: 0 kB 等待被写回到磁盘的大小
Writeback: 0 kB 正在被写回的大小
AnonPages: 78876 kB 未映射页的大小
Mapped: 28556 kB 设备和文件映射大小
Shmem: 10160 kB 已经被分配的共享内存大小
Slab: 102916 kB 内核数据结构缓存大小
SReclaimable: 49616 kB 可收回slab的大小
SUnreclaim: 53300 kB 不可回收的slab的大小
KernelStack: 4416 kB kernel消耗的内存
PageTables: 6028 kB 管理内存分页的索引表的大小
NFS_Unstable: 0 kB 不稳定页表的大小
Bounce: 0 kB 在低端内存中分配一个临时buffer作为跳转,把位于高端内存的缓存数据复制到此处消耗的内存
WritebackTmp: 0 kB USE用于临时写回缓冲区的内存
CommitLimit: 2441436 kB 系统实际可分配内存总量
Committed_AS: 308028 kB 当前已分配的内存总量
VmallocTotal: 34359738367 kB 虚拟内存大小
VmallocUsed: 179588 kB 已经被使用的虚拟内存大小
VmallocChunk: 34359310332 kB malloc 可分配的最大的逻辑连续的内存大小
HardwareCorrupted: 0 kB 删除掉的内存页的总大小(当系统检测到内存的硬件故障时)
AnonHugePages: 6144 kB 匿名 HugePages 数量
CmaTotal: 0 kB 总的连续可用内存
CmaFree: 0 kB 空闲的连续内存
HugePages_Total: 0 预留HugePages的总个数
HugePages_Free: 0 池中尚未分配的 HugePages 数量
HugePages_Rsvd: 0 表示池中已经被应用程序分配但尚未使用的 HugePages 数量
HugePages_Surp: 0 这个值得意思是当开始配置了20个大页,现在修改配置为16,那么这个参数就会显示为4,一般不修改配置,这个值都是0
Hugepagesize: 2048 kB 每个大页的大小
DirectMap4k: 108416 kB 映射TLB为4kB的内存数量
DirectMap2M: 940032 kB 映射TLB为2M的内存数量
DirectMap1G: 0 kB 映射TLB为1G的内存数量
https://www.cnblogs.com/arnoldlu/p/12063591.html
https://testerhome.com/articles/20547
https://segmentfault.com/a/1190000024435739 https://www.cnblogs.com/csnd/p/11807654.html
dump memory /tmp/0x7fb9b0000000-0x7fb9b3ffe000.dump 0x7fb9b0000000 0x7fb9b3ffe000
显示长度超过10字符的字符串