60 second Q & A: new underlying principle

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

  1. 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:

  1. If no default constructor is defined for any class, it will be synthesized; [b no constructor]
  2. 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

  1. https://www.etalabs.net/overcommit.html
  2. https://www.cnblogs.com/GyForever1004/p/8439397.html

Added by antoine on Tue, 11 Jan 2022 04:20:10 +0200