Linux: How to put a load on system memory?
I didn't understand very well if you want to generate arbitrary CPU load or CPU utilization. Yes, they are different things indeed. I'll try to cover both problems.
First of all: load is the average number of processes in the running, runnable or waiting for CPU scheduler queues in a given amount of time, "the one that wants your CPU" so to speak.
So, if you want to generate arbitrary load (say 0.3) you have to run a process for 30% of the time and then remove it from the run queue for 70% of the time, moving it to the sleeping queue or killing it, for example.
You can try this script to do that:
export LOAD=0.3
while true
do yes > /dev/null &
sleep $LOAD
killall yes
sleep `echo "1 - $LOAD" | bc`
done
Note that you have to wait some time (1, 10 and 15 minutes) to get the respective numbers to come up, and it will be influenced by other processes in your system. The more busy your system is the more this numbers will float. The last number (15 minutes interval) tends to be the most accurate.
CPU usage is, instead, the amount of time for which CPU was used for processing instructions of a computer program.
So, if you want to generate arbitrary CPU usage (say 30%) you have to run a process that is CPU bound 30% of the time and sleeps 70% of it.
I wrote an example to show you that:
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <math.h>
#include <sys/time.h>
#include <stdarg.h>
#include <sys/wait.h>
#define CPUUSAGE 0.3 /* set it to a 0 < float < 1 */
#define PROCESSES 1 /* number of child worker processes */
#define CYCLETIME 50000 /* total cycle interval in microseconds */
#define WORKTIME (CYCLETIME * CPUUSAGE)
#define SLEEPTIME (CYCLETIME - WORKTIME)
/* returns t1-t2 in microseconds */
static inline long timediff(const struct timeval *t1, const struct timeval *t2)
{
return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec);
}
static inline void gettime (struct timeval *t)
{
if (gettimeofday(t, NULL) < 0)
{
err(1, "failed to acquire time");
}
}
int hogcpu (void)
{
struct timeval tWorkStart, tWorkCur, tSleepStart, tSleepStop;
long usSleep, usWork, usWorkDelay = 0, usSleepDelay = 0;
do
{
usWork = WORKTIME - usWorkDelay;
gettime (&tWorkStart);
do
{
sqrt (rand ());
gettime (&tWorkCur);
}
while ((usWorkDelay = (timediff (&tWorkCur, &tWorkStart) - usWork)) < 0);
if (usSleepDelay <= SLEEPTIME)
usSleep = SLEEPTIME - usSleepDelay;
else
usSleep = SLEEPTIME;
gettime (&tSleepStart);
usleep (usSleep);
gettime (&tSleepStop);
usSleepDelay = timediff (&tSleepStop, &tSleepStart) - usSleep;
}
while (1);
return 0;
}
int main (int argc, char const *argv[])
{
pid_t pid;
int i;
for (i = 0; i < PROCESSES; i++)
{
switch (pid = fork ())
{
case 0:
_exit (hogcpu ());
case -1:
err (1, "fork failed");
break;
default:
warnx ("worker [%d] forked", pid);
}
}
wait(NULL);
return 0;
}
If you want to eat up a fixed amount of RAM you can use the program in the cgkanchi's answer.
Retrieve CPU usage and memory usage of a single process on Linux?
ps -p <pid> -o %cpu,%mem,cmd
(You can leave off "cmd" but that might be helpful in debugging).
Note that this gives average CPU usage of the process over the time it has been running.
How to get the memory and cpu usage of a remote server?
After searching online and combining a few answers from other questions on stackflow. I get the following solution.
Solution
On your local computer, you might want to have the following bash script, named, say, usage_ssh
START=1
END=3
date
for i in $(seq $START $END)
do
printf '=%.0s' {1..50};
printf '\n'
echo myservery$i
ssh myserver$i -o LogLevel=QUIET -t "~/bin/usage"
done
printf '=%.0s' {1..50};
printf '\n'
printf 'CPU Load: \n'
printf 'First Field\tprocesses per processor\n'
printf 'Second Filed\tidling percentage in last 5 minutes\n'
printf '\n'
printf '\n'
On your remote server, you should have the following bash script named usage
. This script should be located in ~/bin
.
free -m | awk 'NR==2{printf "Memory Usage\t%s/%sMB\t\t%.2f%\n", $3, $2, $3/$2*100}';
top -n 1 | grep load | awk '{printf "CPU Load\t%.2f\t\t\t%.2f\n", $(NF-2), $(NF-1)}';
Explanation
The idea is that You will call the use ssh -t <your command>
to run executable on your remote file and get the output on the screen of your local computer.
Output
Sat Mar 28 10:32:34 CDT 2020
==================================================
myserver1
Memory Usage 47418/48254MB 98.27%
CPU Load 0.01 0.02
==================================================
myserver2
Memory Usage 47421/48254MB 98.27%
CPU Load 0.01 0.02
==================================================
myserver3
Memory Usage 4300/84541MB 5.09%
CPU Load 0.02 0.02
==================================================
CPU Load:
First Field processes per processor
Second Filed idling percentage in last 5 minutes
How to log the memory consumption on Linux?
A small script like
rm memory.log
while true; do free >> memory.log; sleep 1; done
How do we Load Linux Image to appropiate location in Memory
from file position 0x1000
means what it says. You have it in the dump:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
...
[ 1] .text PROGBITS c5000000 001000 5ac13e 00 AX 0 0 4096
It's where the .text
section starts in the file, at offset 0x1000
.
But one thing we can see here .text section is greater than DRAM end address
Nope, it's not greater (not in the sense of bigger, at least), it's compiled in the expectation that it'll be loaded at address 0xc5000000
in the memory.
so image should not be loded properly though we are not getting any error after loading first section it keeps on loading other sections
The image can be loaded anywhere, it's just data for the purpose of loading.
OTOH, if loading section to address 0xc5000000
means what it says, the file gets loaded into nowhere since your RAM ends at 0x7fffffff
.
but after this message it hangs.
And that's expected. Machine code is rarely position-independent and so if you load it at a location different from where it's supposed to be loaded, it'll not work. Or if it doesn't even get loaded, then what are you going to execute? Garbage.
Is there any way to set these section addresses before compilation??
Depending on the system you may have one of the two below options or both:
- set up page translation in such a way that virtual addresses from
0xc5000000
and up map to physical addresses from0x5000000
and up for the entire program - find the linker script that your compiler is using and change the initial section address from
0xc5000000
to0x5000000
, google this up, see compiler/linker documentation
Also, it's a bit odd that the entry point is at 0x5000000
. Not that this is necessarily wrong, it's just that it's rarely the case. I'd make sure that the start
label (or _start
or whatever it is) indeed receives the same address as the beginning of the .text
section. If, for some reason, it's not the case, there's something wrong either with the linker script or the compiler/linker command-line options or with the loader.
Linux CPU and memory percentages
Put the following snippet somewhere in a script:
#!/bin/bash
CPU=$(lscpu | grep '\(CPU\|max\) MHz:' | xargs echo | awk '{printf "%3.0f\n", $3*100/$7}')
MEM=$(free | grep Mem | awk '{printf "%3.0f\n", $3*100/$2}')
echo CPU $CPU% \| MEM $MEM%
And call it from genmon as bash /path/to/this/script.sh
.
Behavior of the Kernel under high memory load
Sorry to answer my own question, but I like to have a record of solutions. The article linked by sawdust contains what I needed.
- The kernal activates the out-of-memory manager (mm/oom_kill.c in the Linux kernel) when it runs out of allocatable memory.
- The OOM manager uses some heuristics to determine which process should be killed. Total runtime of a process reduces the chance of death, while memory allocated increases it. There are other factors, but they don't matter for me.
- After picking a process, the OOM sends it SIGTERM.
There are two reasons for why, in my case, all processes except the one that's hogging the memory get killed.
My process ignores SIGTERM during the region where it is allocating memory. This might be because the process is actively receiving lots of other signals during this time, and/or because the process is blocking for I/O during much of the remaining time. In anycase, it ignores SIGTERM.
The process that is hogging all the memory typically has been running for a long time, accumulating RAM for a few hours. Even though it has about 4 times as much as any other process, it's long runtime (several hundred times longer than others) might cause the OOM manager to pick other processes to terminate first.
Solutions:
Running:
ulimit -v memamount
for a particular user changes the maximum amount of memory the user can allocate with a single process to memamount. This can prevent the OOM manager from activating. Instead, malloc calls will fail, which I can detect.
2: Writing a handler for SIGTERM that gracefully cleans up might help, but only if the OOM is actually sending SIGTERM to the process, and the process is ignoring or failing to receive SIGTERM.
3: Set the memory limit from within your code (C):
//resource limit structure with both hard and soft max set to 2GB.
struct rlimit memmax; memmax.rlim_max=0x7FFFFFFF; memmax.rlim_cur = 0x7FFFFFFF;
setrlimit(RLIMIT_MEMLOCK,&memmax); //set maximum virtual memory space to 2GB.
How to set CPU load on a Red Hat Linux box?
This is exactly what you need (internet archive link):
https://web.archive.org/web/20120512025754/http://weather.ou.edu/~apw/projects/stress/stress-1.0.4.tar.gz
From the homepage:
"stress is a simple workload generator for POSIX systems. It imposes a configurable amount of CPU, memory, I/O, and disk stress on the system. It is written in C, and is free software licensed under the GPL."
Memory usage of current process in C
You can always just open the 'files' in the /proc
system as you would a regular file (using the 'self' symlink so you don't have to look up your own pid):
FILE* status = fopen( "/proc/self/status", "r" );
Of course, you now have to parse the file to pick out the information you need.
system loads in GNU screen's hardstatus line
To keep it short:
The three numbers stand for average cpu load during the last minute, 5 minutes and 15 minutes where 0 means 0% load and 1.0 means 100% load.
Have a look at this excellent explanation of the cpu load.
For the second question I'm not sure if you can express the system load with only one number in the hardstatus line of screen (I don't think so), but I hope my answer helped a little bit ;-) *Jost
Related Topics
"Must Be Connected to a Terminal Error" with Screen -X Command on a Linux Container
Shared Volume in Docker Through Vagrant
Executing Exe or Bat File on Remote Windows Machine from *Nix
Sudo Apt-Get Update Fail on Ubuntu 17.04
Getting Following Error After The Command Sudo Apt-Get Update on Ubuntu 16.04
Expect, Interact and Then Again Expect
What Is The Size of Coap Packet
Linux Asynch Io - Difference Between Aio.H and Libaio.H
Bash: Split Stdout from Multiple Concurrent Commands into Columns
Qemu on Raspberry Pi Arch Linux Latest Sd Image
Copy Lines Containing Word from One File to Another File in Linux
Autoconf Complains "C Compiler Cannot Create Executables" on Linux Mint
Pcre Issue When Setting Up Wsgi Application
How to Manually Install The Eclipse-Cdt Plugin from an Archive/Zip on Ubuntu
Unix Domain Sockets Not Accessable Across Users