
Historical review
- I have failed many times, and I feel that I have summarized a lot [virtual function]
- The next time someone asks a more difficult question, or you don't understand the [construction and deconstruction order]
This week's reading: explore the C + + object model in depth
https://mp.weixin.qq.com/s/pAoIe9m2Oat7d8c_ZW5Qyg
C + + object model constructor semantics
https://mp.weixin.qq.com/s/z246VYFrR9zDzIWZTS5yWA
Memory layout of C + + objects (Part 1) https://coolshell.cn/articles/12176.html
Reading income
Q: a service has 1G memory. Can you apply for 2G memory through malloc?

Step 1: understand the meaning of the parameter memory overcommit and test it
- Can do man malloc
Key points: the non null address returned by malloc is not guaranteed to be available
The malloc() function allocates size bytes and returns a pointer to the allocated memory.
The memory is not initialized. [No initialization, no physical memory allocated, staic variable]
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. [on Linux, malloc never fails. It always returns a pointer to allocated memory, but later, if there is not enough physical memory available, your application may crash when trying to access that memory.]
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
60 seconds thinking: what's the use of variables without initialization? Variables initialized for are weak symbols
- cat /proc/sys/vm/overcommit_memory 0 default
- continue
0 – This is the default value. Take a try attitude: OVERCOMMIT_GUESS[If you can't, just pull it Can be overused swap,It means that you can apply for too much memory, but not too much [the measurement standard is not clear] 1 – Always overcommit. allow overcommit,Memory applications are not rejected. [no restrictions] 2 – Don't overcommit. prohibit overcommit. [[recommended practice] Total requested memory exceeds CommitLimit Even if it is overcommit. The formula is as follows: [CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap] No more than swap+50% of physical memory% 0 - Heuristic overcommit handling. [It's impossible to apply too much, Deng jia1] Obvious overcommits of address space are refused. Used for a typical system. Itensures a seriously wild allocation fails while allowing overcommit to reduce swap usage. root is allowed to allocate slightly more memory in this mode. This is the default. 1 - Always overcommit.[No refusal] Appropriate for some scientific applications. Classic example is code using sparse arrays and just relying on the virtual memory consisting almost entirely of zero pages. 2 - Don't overcommit(It is not allowed to apply for too large). The total address space commit for the system is not permitted to exceed swap + a configurable amount (default is 50%) of physical RAM. Depending on the amount you use, in most situations this means a process will not be killed while accessing pages but will receive errors on memory allocation as appropriate.
grep -i commit /proc/meminfo CommitLimit: 1464112 kB [CommitLimit namely overcommit [threshold of] Committed_AS: 608060 kB [Already applied Committed_As]
- Why is configuration 2 [excessive memory usage is a program problem that should not be handled by the os, and the os prompts an error]
Step 2: problem restore: VM overcommit_ Test with memory = 2
2.1 problem restore memory request allocation failure
- Executing any command is wrong; bash: fork: unable to allocate memory
There is not enough memory in 2ge memory.
echo 2 >>/proc/sys/vm/overcommit_memory cat /proc/sys/vm/overcommit_memory Results perform any sell All commands report errors cat /proc/sys/vm/overcommit_memory [shell fork A process exec ] s -bash: fork: Unable to allocate memory[ shell fork A process exec ]
Solution: Tencent virtual machine security protection (cloud mirror unloading)
/usr/local/qcloud/YunJing/uninst.sh
2.2 problem restore: VM overcommit_ The test with memory = 2 proves that malloc application fails. [use with caution]
-bash: fork: unable to allocate memory
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> int main() { char* p=NULL; while(1) { p=malloc(sizeof(int)*1000); if(NULL==p) { break; } /* The following sentence ensures that the applied memory is valid and can be used. In the memory allocation principle, if the allocated memory is not used, the nonexistent memory can be allocated in advance and wait for the memory to be released, */ memset(p,0x00,100); usleep(10); } while(1) { sleep(1); } return 0; }
An error will be reported when executing any command, including the situation that makes it impossible to log in. This test caused the service to become unavailable
[root@VM-0-10-centos demo]# ./a.out -bash: fork: cannot allocate memory gcc 33.c -bash: fork: cannot allocate memory free -m -bash: fork: cannot allocate memory ls -ltra /proc [Unable to delete process] -bash: fork: cannot allocate memory top -bash: fork: cannot allocate memory shutdown -r now -bash: fork: cannot allocate memory
Understand swap: vm.net is not enabled overcommit_ The test with memory = 2 failed
- free view: swap =0;
$ free -m
# The output is as follows # total used free shared buff/cache available # Mem: 7976 4979 328 124 2669 2703 # Swap: 0 0 0
- vm.overcommit_memory =2, the limit is very small
- The virtual memory of windows is automatically set by the computer
- The swap partition of Linux is divided when you install the system. Swap is a special file (or partition) located on the disk and belongs to "virtual memory"
Swap space in Linux is used when the amount of physical memory (RAM) is full
Virtual memory is called swap
- open
echo 60 >/proc/sys/vm/swappiness
centos Turn on virtual memory 1 mkdir /swaps 2 cd /swaps 3 dd if=/dev/zero of=swaps bs=512k count=4096 swap Size bs*count=4096*512/1024/1024=(2G) 4 swapon /swaps/swaps 5 Boot mount cat /etc/fstab /swaps/swaps swap swap defaults 0 0
Summary overcommit_memory three cases
1 always allow swap
2 it is not allowed after more than half of the swap + physical memory [this is the most correct setting, but use it with caution. Once the memory leak causes the machine to fail to log in, be sure to turn on swap]
0 fails if it exceeds swap
Key points: no matter which method is adopted, malloc's principle is virtual memory (a continuous piece of space on the disk) and overcommit_ swap must be enabled regardless of memory:
Step 2: check the code to understand the meaning of parameters
Kernel parameters vm.overcommit_memory The source code corresponding to the values 0, 1 and 2 of is as follows, Source file: https://github.com/torvalds/linux/blob/master/include/linux/mman.h #define OVERCOMMIT_GUESS 0 #define OVERCOMMIT_ALWAYS 1 #define OVERCOMMIT_NEVER 2 extern int sysctl_overcommit_memory; extern int sysctl_overcommit_ratio; https://github.com/torvalds/linux/blob/master/mm/mmap.c
Determine when to allocate physical memory
C + + novices generally have two common misunderstandings:
- If no default constructor is defined for any class, it will be synthesized; [b no constructor]
- The default constructor synthesized by the compiler will explicitly set the "default value of each data member in the class" [b execution]

In the following four cases, the compiler synthesizes constructors
- case 1 is a member class object with "default constructor" in a class;
- case 2: when a class is derived from a base class with a default constructor;
- case 3 when a class declares (or inherits) a virtual function;
- case 4 when a class derives from an inheritance chain, there are one or more virtual base class es

When virtual function is declared in a class
- The compiler will generate a virtual function table containing the virtual functions address of class;
- In each class object, the compiler will synthesize a pointer member (vptr) to point to the vtbl (virtual function table) of the class
https://godbolt.org/z/P5h1Phfn4

- Construction execution order of C + + multiple inheritance:
The execution of the constructor is divided into two stages:
1 initialization phase
- If it is an inherited class, according to the left to right inheritance order,
- If it is a member variable, the top-down declaration order of class members
2 assignment stage (code sequence in constructor)
1.Firstly, the constructor of virtual base class is executed, and the constructors of multiple virtual base classes are constructed in the inherited order; [sequential construction of inheritance] 2.Execute the constructor of the base class, and the constructors of multiple base classes are constructed in the inherited order; [sequential construction of inheritance] 3.Execute the constructor of the member object, and the constructors of multiple member objects are constructed in the declared order; [order of declaration] 4.Execute the constructor of the derived class itself; 5.Deconstruction is performed in the reverse order of construction; [execute in reverse order] conclusion When a class is constructed (with inheritance and composition), Execute the constructor of the virtual inherited parent class first, Then execute the constructor of the normal inherited parent class from left to right, Then initialize the data members in the defined order, Finally, it is the call of its own constructor. The destructor is the exact opposite and mirrors each other
Example 1
Inheritance and list initialization In the following example B Class inherits A and C,Then have another one A and C Although the member variables of type do not conform to the design pattern, they will see. #include <iostream> #include <cmath> using namespace std; class A { public: A(){cout << "Construct A" << endl;} ~A(){cout << "Destruct A" << endl;} }; class C { public: C(){cout << "Construct C" << endl;} ~C(){cout << "Destruct C" << endl;} }; class B: public A, public C { public: //Notice: List initialize B(): a(A()), c(C()) {cout << "Construct B" << endl;} ~B(){cout << "Destruct B" << endl;} C c; A a; }; int main(int argc, char const *argv[]) { B b; return 0; }
In such an example, the output is like this~
- Construction sequence
Construct A / / inherit order from left to right Construct C / / inherit order from left to right
Construct C / / top-down declaration order of class members Construct A / top-down declaration order of class members
Construct B / / own
Destruct A / / bottom-up declaration order of class members
Destruct C / / bottom-up declaration order of class members
Destruct C / / right to left inheritance order
Destruct A / / right to left inheritance order
- Destructions are performed in the reverse order of construction Destruct B / / self
Example 2
https://www.cnblogs.com/GyForever1004/p/8439397.html
Giant shoulder
- https://www.etalabs.net/overcommit.html
- https://www.cnblogs.com/GyForever1004/p/8439397.html