Created
September 18, 2023 20:01
-
-
Save craigloewen-msft/496078591e0bbbfdec9f144c6b50a8cc to your computer and use it in GitHub Desktop.
Auto memory reclaim shell script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Put under /etc/autoMemoryReclaim.sh | |
# set variables at the top | |
low_cpu_usage=50 # Note: We work with integer percentages (e.g., 50%) | |
idle_time=2 # Minutes | |
cached_memory_limit=1000 # MB | |
percent_memory_to_reclaim=5 # Percentage as an integer | |
wait_period=3 | |
# function to check if user is idle | |
is_idle() { | |
loadavg=$(cat /proc/loadavg) | |
load1=$(echo "$loadavg" | awk '{print $1}') | |
load5=$(echo "$loadavg" | awk '{print $2}') | |
load15=$(echo "$loadavg" | awk '{print $3}') | |
if (( $(echo "$load15 < $low_cpu_usage" | bc -l) )) && (( $(echo "$load1 < $low_cpu_usage" | bc -l) )) && (( $(echo "$load5 < $low_cpu_usage" | bc -l) )); then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# function to get cached memory | |
get_cached_memory() { | |
mem_info=$(free -m | grep "^Mem:" | awk '{print $6}') | |
echo "$mem_info" | |
} | |
# initialize state | |
state="waiting_to_be_idle" | |
idle_counter=0 | |
while true; do | |
if [[ $state == "waiting_to_be_idle" ]]; then | |
if is_idle; then | |
((idle_counter++)) | |
echo "User is idle for $idle_counter minutes" | |
if ((idle_counter >= idle_time)); then | |
state="reclaiming_memory" | |
echo "User has been idle for $idle_time minutes, now moving to reclaiming memory state" | |
fi | |
else | |
idle_counter=0 | |
echo "User is not idle" | |
fi | |
elif [[ $state == "reclaiming_memory" ]]; then | |
if is_idle; then | |
mem_cached=$(get_cached_memory) | |
echo "Mem cached: $mem_cached ! and $cached_memory_limit" | |
if [[ "$mem_cached" -lt "$cached_memory_limit" ]]; then | |
state="waiting_to_be_idle" | |
echo "Cached memory limit of $cached_memory_limit MB reached, now moving back to waiting to be idle state" | |
else | |
mem_total=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo) | |
mem_to_reclaim=$((mem_total * percent_memory_to_reclaim / 100)) | |
echo "Reclaiming $mem_to_reclaim MB of memory" | |
echo "${mem_to_reclaim}M" | sudo tee -a /sys/fs/cgroup/unified/memory.reclaim | |
sleep $wait_period | |
fi | |
else | |
state="waiting_to_be_idle" | |
echo "User is not idle, now moving back to waiting to be idle state" | |
fi | |
fi | |
# check every minute | |
sleep $wait_period | |
done | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Used if you want to log your memory values over time to see the behaviour. | |
csv_file="output.csv" | |
# Create the CSV file if it doesn't exist | |
if [[ ! -f "$csv_file" ]]; then | |
echo "Seconds Since Starting,Used Memory (MB),Cached Memory (MB),Free Memory (MB),1 Min CPU,5 Min CPU,15 Min CPU,Total Memory Available (MB),Total Memory Used by vmmemwsl (MB)" > "$csv_file" | |
fi | |
# Define conversion constants | |
MB=$((1024 * 1024)) | |
# Start time | |
start_time=$(date +%s) | |
while true; do | |
echo "Collecting system information..." | |
# Get system memory information in bytes | |
mem_info=$(free -b | grep "Mem:") | |
used_mem=$(echo "$mem_info" | awk '{print $3}') | |
cached_mem=$(echo "$mem_info" | awk '{print $6}') | |
free_mem=$(echo "$mem_info" | awk '{print $4}') | |
# Convert memory values to megabytes | |
used_mem_mb=$((used_mem / MB)) | |
cached_mem_mb=$((cached_mem / MB)) | |
free_mem_mb=$((free_mem / MB)) | |
# Get CPU load averages | |
load_1min=$(cat /proc/loadavg | awk '{print $1}') | |
load_5min=$(cat /proc/loadavg | awk '{print $2}') | |
load_15min=$(cat /proc/loadavg | awk '{print $3}') | |
# Get total memory available in Windows | |
echo "Fetching total memory available in Windows..." | |
total_mem_avail=$(powershell.exe "(Get-CimInstance -ClassName Win32_OperatingSystem).FreePhysicalMemory" | sed 's/\r$//') | |
# Convert total memory available to megabytes | |
total_mem_avail_mb=$((total_mem_avail / 1024)) | |
# Get total memory used by vmmemwsl process | |
echo "Fetching total memory used by vmmemwsl process..." | |
total_mem_vmmem=$(powershell.exe "(Get-Process -Name vmmemwsl | Measure-Object -Property WS -Sum).Sum" | sed 's/\r$//') | |
# Convert total memory used by vmmemwsl to megabytes | |
total_mem_vmmem_mb=$((total_mem_vmmem / MB)) | |
# Calculate seconds since starting | |
current_time=$(date +%s) | |
seconds_since_start=$((current_time - start_time)) | |
# Append the values to the CSV file | |
echo "Appending system information to $csv_file..." | |
echo "$seconds_since_start,$used_mem_mb,$cached_mem_mb,$free_mem_mb,$load_1min,$load_5min,$load_15min,$total_mem_avail_mb,$total_mem_vmmem_mb" >> "$csv_file" | |
echo "System information collected and logged successfully." | |
# Wait for 1 second before the next iteration | |
echo "Waiting for the next iteration..." | |
sleep 10 | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Make sure your /etc/wsl.conf file looks like this to have the script auto start on start up of your WSL distro | |
[boot] | |
command=/etc/autoMemoryReclaim.sh |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment