"When you define so many global variables, the system allocates several hundred KB to you. Is this too much memory consumption ?", Asked one.
I have heard that there are limited resources in the embedded system, and there is no space to allocate. Pay attention to resource conservation (... It seems that the configuration of Mi Shen 4 is about to blow up my thinkpad ...). Does the use of global variables really occupy a large system of memory, and the system actually allocates several hundred KB of space to me?
I don't believe it, so I want to try:
Global variables must occupy the memory, but no matter whether they are global variables or not, as long as they are defined variables, they will occupy the memory. This has nothing to do with whether it is global or not, the occupied area is different (For details, refer to APUE memory P153 ).
How can the system give me several hundred KB of space? How can I use tens of megabytes of resources for QQ on my android server?
The following is my exploration content.
Obtain the maximum length of the stack of the current process in bytes:
# Define getLimit (name) get_limits (# name, name) // This # Is a string creation character, you can create a string in a macro // just print it to determine whether it is a specific value or a string void print_infinite (rlim_t t) {if (RLIM_INFINITY = t) {printf ("% 14 s ", "infinite");} else {printf ("% 14ld", t/1024/1024);} // encapsulate the maximum static void get_limits (char * name, int resource) {struct rlimit limit; if (getrlimit (resource, & limit )! = 0) {printf ("get limit error % s \ n", strerror (errno);} printf ("%-14 s", name); print_infinite (limit. rlim_cur); print_infinite (limit. rlim_max); putchar ('\ n') ;}// the entry function to obtain the maximum value of the process stack void GetProcessHeapAndStackLimitSize () {printf (PARTING_LINE ); printf ("%-14 s", "Name"); printf ("% 13 s", "LimCur (MB)"); printf ("% 13 s \ n ", "LimMax (MB)"); // Maximum length of the RLIMIT_DATA segment: initialized data, non-initialized data, and total heap getLimit (RLIMIT_DATA ); // getLimit (RLIMIT_STACK); printf ("\ n ");}
A small method used to test whether data is obtained correctly:
Recursive call consumes the system once each callStack ZoneThe size is 1 MB. The automatic variables and the information to be saved for each function call are stored inStack.
// Used to test whether the maximum value of the heap is void GetStackSize () {static int I = 1; char xxx [1024*1024]; // 1 MB printf ("now I is: % d \ n ", I); GetStackSize (++ I );}
Write a main function. First call the GET method to obtain the stack value and then call the test function. The result is as follows:
=============================== GetProcessHeapAndStackLimitSize ================================= Name LimCur(MB) LimMax(MB) RLIMIT_DATA infinite infinite RLIMIT_STACK 8 infinite now i is : 1now i is : 2now i is : 3now i is : 4now i is : 5now i is : 6now i is : 7Segmentation fault (core dumped)
Infinite can be understood as unlimited. The result shows that the current process's heap zone (in fact, this method obtainsNot in a strict sense.The obtained data includes the initialization data, non-initialization data, and the total number of heap areas.
There is no limit, but the stack system only allocates 8 M space. That is to say, the total number of local variables you can use in the current process cannot exceed 8 M, otherwise, an error occurs (Segmentation Fault).
If so, then what will happen when I directly define char xxx [8*1024*1024] in the main function? Obviously, a segment error occurs when nothing is executed.
8 m is obviously not enough for me, especially when I need various buffers, how should I "resize? Or if my system does not have enough memory to occupy too much memory for some applications, how can I limit its memory usage?
The following describes how to modify the default system configuration:
// Encapsulate the maximum value of static void set_limits (char * name, int resource, rlim_t cur, rlim_t max) {struct rlimit limit; limit. rlim_cur = cur; limit. rlim_max = max; if (setrlimit (resource, & limit )! = 0) {printf ("get limit error % s \ n", strerror (errno);} else {printf ("% s OK \ n ", __func __, name) ;}} void SetProcessHeapAndStackLimitSize () {printf (PARTING_LINE); // Maximum length of the RLIMIT_DATA data segment: total initialization data, non-initialization, and heap rlim_t pref = 10*1024*1024; setLimit (RLIMIT_DATA, pref, pref * 2 ); // setLimit (RLIMIT_STACK, pref * 2, pref * 4 );}
What will the setting result look like? We can set it first, and then call the GET method again to check whether the setting is successful.
// Main function int main (int argc, char ** argv) {GetProcessHeapAndStackLimitSize (); // GetStackSize (); // before resetting, setProcessHeapAndStackLimitSize (); GetProcessHeapAndStackLimitSize (); GetStackSize (); // if it is set, 19 is returned and the system crashes.
Ruturn 0;
}
The result is as follows:
=============================== GetProcessHeapAndStackLimitSize ================================= Name LimCur(MB) LimMax(MB) RLIMIT_DATA infinite infinite RLIMIT_STACK 8 infinite =============================== SetProcessHeapAndStackLimitSize ================================= set_limits RLIMIT_DATA OK set_limits RLIMIT_STACK OK =============================== GetProcessHeapAndStackLimitSize ================================= Name LimCur(MB) LimMax(MB) RLIMIT_DATA 10 20 RLIMIT_STACK 20 40 now i is : 1now i is : 2now i is : 3now i is : 4now i is : 5now i is : 6now i is : 7now i is : 8now i is : 9now i is : 10now i is : 11now i is : 12now i is : 13now i is : 14now i is : 15now i is : 16now i is : 17now i is : 18now i is : 19Segmentation fault (core dumped)
As expected, if the parameter is successfully modified, we can use more stack zones or restrict the use of stack zones.
However, when we run the program multiple times, we find an interesting phenomenon: Although we have successfully set the program, after re-running the program, the system will only allocate 8 M to us, we can see that this change only takes effect for the current process settings. How can this change take effect for all the systems? See the breakdown below.
After learning about these things, we may sometimes encounter a program that fails for no reason and no error information is printed. If GDB doesn't even tell where the problem is, everyone may have to think about it, whether it is restricted by the system.
The source code has been uploaded.