Skip to content

Instantly share code, notes, and snippets.

@lpenguin
Last active December 8, 2017 11:26
Show Gist options
  • Save lpenguin/79e13ef0df062a6eae74b2e9d239a930 to your computer and use it in GitHub Desktop.
Save lpenguin/79e13ef0df062a6eae74b2e9d239a930 to your computer and use it in GitHub Desktop.
MemEater
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace MemEater
{
static class MainClass
{
private static readonly Random Random = new Random();
private const Int64 Kilobyte = 1024;
private const Int64 Megabyte = Kilobyte * 1024;
private const Int64 Gigabyte = Megabyte * 1024;
private static string StrSize(Int64 bytes)
{
if (bytes >= Gigabyte) {
return $"{bytes /(float) Gigabyte: 0.##} Gbytes ({bytes} bytes)";
}
if (bytes >= Megabyte) {
return $"{bytes / (float)Megabyte: 0.##} Mbytes ({bytes} bytes)";
}
if (bytes >= Kilobyte) {
return $"{bytes / (float)Kilobyte: 0.##} Kbytes ({bytes} bytes)";
}
return $"{bytes} bytes";
}
public static void Main(string[] args)
{
var step = Megabyte;
if (args.Length >= 1) {
step = int.Parse (args [0]);
}
var numThreads = 1;
if (args.Length >= 2) {
numThreads = int.Parse (args [1]);
}
Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}");
Console.WriteLine($"Increment size: {step } bytes");
Console.WriteLine($"Creating {numThreads} threads");
for (var i = 0; i < numThreads; i++)
{
var t = new Thread(Work) {Name = $"Eater#{i}"};
t.Start(step);
}
while (true)
{
Thread.Sleep(5000);
{
Process currentProc = Process.GetCurrentProcess();
Console.WriteLine ($"Process size: {StrSize(currentProc.PrivateMemorySize64)}");
Console.WriteLine ();
}
}
}
private class Node {
public byte[] data;
public Node prev;
}
public static void Work (object param)
{
Console.WriteLine($"Thread {Thread.CurrentThread.Name} started");
var step = (Int64)param;
var start = DateTime.Now;
Node prev = null;
while(true) {
var data = new byte[step + (long)(Random.NextDouble() * step)];
var node = new Node();
node.data = data;
node.prev = prev;
prev = node;
for (var j = 0; j < data.Length; j += 10) {
data [j] = 10;
}
}
}
}
}
@lpenguin
Copy link
Author

lpenguin commented Dec 8, 2017

nikita@nikita-OptiPlex-9020:~/MemEater$ MONO_GC_PARAMS=max-heap-size=1g mono MemEater.exe 50000
Process ID: 3074
Increment size: 50000 bytes
Creating 1 threads
Thread Eater#0 started

Unhandled Exception:
OutOfMemoryException
[ERROR] FATAL UNHANDLED EXCEPTION: System.OutOfMemoryException: Out of memory
  at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_gc_alloc_vector (intptr,intptr,intptr)
  at (wrapper alloc) System.Object:AllocVector (intptr,intptr)
  at MemEater.MainClass.Work (System.Object param) <0x415cf030 + 0x0010d> in <filename unknown>:0 
  at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) <0x7f62744b1010 + 0x000d0> in <filename unknown>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, Boolean preserveSyncCtx) <0x7f62744af850 + 0x0016e> in <filename unknown>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, Boolean preserveSyncCtx) <0x7f62744af820 + 0x00020> in <filename unknown>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) <0x7f62744af770 + 0x00059> in <filename unknown>:0 
  at System.Threading.ThreadHelper.ThreadStart (System.Object obj) <0x7f62744b1120 + 0x0004c> in <filename unknown>:0 

@lpenguin
Copy link
Author

lpenguin commented Dec 8, 2017

nikita@nikita-OptiPlex-9020:~/MemEater$ sudo sysctl -w vm.max_map_count=8000
[sudo] password for nikita: 
vm.max_map_count = 25000
nikita@nikita-OptiPlex-9020:~/MemEater$ mono MemEater.exe 128 120 2>&1 | tee log.txt
Process ID: 4529
Increment size: 128 bytes
Creating 120 threads
Thread Eater#1 started
Thread Eater#0 started
Thread Eater#2 started
Thread Eater#3 started
Thread Eater#4 started
Thread Eater#5 started
Thread Eater#6 started
Thread Eater#7 started
Thread Eater#8 started
Thread Eater#9 started
... A lot of output ...
Thread 2 (Thread 0x7f0df0fff700 (LWP 4531)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x00000000005fdcdb in ?? ()
#2  0x00007f0df22756ba in start_thread (arg=0x7f0df0fff700) at pthread_create.c:333
#3  0x00007f0df1fab3dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7f0df2da9780 (LWP 4529)):
#0  0x00007f0df1ed9826 in __GI___sigsuspend (set=0x956e00) at ../sysdeps/unix/sysv/linux/sigsuspend.c:30
#1  0x00000000005cc5e4 in ?? ()
#2  0x00000000005cc73f in ?? ()
#3  <signal handler called>
#4  __clock_nanosleep (clock_id=<optimized out>, flags=1, req=0x7ffd03521260, rem=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:48
#5  0x0000000000617160 in ?? ()
#6  0x000000000058743a in ?? ()
#7  0x0000000041346bb2 in ?? ()
#8  0x00007f0df2cfe230 in ?? ()
#9  0x00007f0df2cfe230 in ?? ()
#10 0x0000000000000078 in ?? ()
#11 0x0000000000000078 in ?? ()
#12 0x0000000000000080 in ?? ()
#13 0x000000000219c080 in ?? ()
#14 0x0000000000000000 in ?? ()

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

From other window:

nikita@nikita-OptiPlex-9020:~/MemEater$ while true ; do pmap 4529 | wc -l; sleep 3 ; done            
7108
8003
8003
8003
8003
8004
8004
8004
8004
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment