diff --git a/py/malloc.c b/py/malloc.c
index c65d38a9687c43d96e76a0ddb85b176f4fafe991..4f01dc63f5208ccba6678b90fbf5f6a9999b4367 100644
--- a/py/malloc.c
+++ b/py/malloc.c
@@ -2,8 +2,15 @@
 #include <stdlib.h>
 
 #include "misc.h"
+#include "mpconfig.h"
 
+#if MICROPY_MEM_STATS
 static int total_bytes_allocated = 0;
+static int current_bytes_allocated = 0;
+static int peak_bytes_allocated = 0;
+
+#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
+#endif
 
 void *m_malloc(int num_bytes) {
     if (num_bytes == 0) {
@@ -14,7 +21,11 @@ void *m_malloc(int num_bytes) {
         printf("could not allocate memory, allocating %d bytes\n", num_bytes);
         return NULL;
     }
+#if MICROPY_MEM_STATS
     total_bytes_allocated += num_bytes;
+    current_bytes_allocated += num_bytes;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -27,7 +38,11 @@ void *m_malloc0(int num_bytes) {
         printf("could not allocate memory, allocating %d bytes\n", num_bytes);
         return NULL;
     }
+#if MICROPY_MEM_STATS
     total_bytes_allocated += num_bytes;
+    current_bytes_allocated += num_bytes;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -41,7 +56,17 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
         printf("could not allocate memory, reallocating %d bytes\n", new_num_bytes);
         return NULL;
     }
-    total_bytes_allocated += new_num_bytes;
+#if MICROPY_MEM_STATS
+    // At first thought, "Total bytes allocated" should only grow,
+    // after all, it's *total*. But consider for example 2K block
+    // shrunk to 1K and then grown to 2K again. It's still 2K
+    // allocated total. If we process only positive increments,
+    // we'll count 3K.
+    int diff = new_num_bytes - old_num_bytes;
+    total_bytes_allocated += diff;
+    current_bytes_allocated += diff;
+    UPDATE_PEAK();
+#endif
     return ptr;
 }
 
@@ -49,8 +74,31 @@ void m_free(void *ptr, int num_bytes) {
     if (ptr != NULL) {
         free(ptr);
     }
+#if MICROPY_MEM_STATS
+    current_bytes_allocated -= num_bytes;
+#endif
 }
 
 int m_get_total_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
     return total_bytes_allocated;
+#else
+    return -1;
+#endif
+}
+
+int m_get_current_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
+    return current_bytes_allocated;
+#else
+    return -1;
+#endif
+}
+
+int m_get_peak_bytes_allocated(void) {
+#if MICROPY_MEM_STATS
+    return peak_bytes_allocated;
+#else
+    return -1;
+#endif
 }
diff --git a/py/misc.h b/py/misc.h
index 9f83ab526f0cb30022c9e6676f6af97506831329..153218ba2f8b6abf03eea3bb2b82d1d1a121cc1c 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -32,6 +32,8 @@ void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes);
 void m_free(void *ptr, int num_bytes);
 
 int m_get_total_bytes_allocated(void);
+int m_get_current_bytes_allocated(void);
+int m_get_peak_bytes_allocated(void);
 
 /** unichar / UTF-8 *********************************************/
 
diff --git a/py/mpconfig.h b/py/mpconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..17c5a770c4967af083a5479cfece9d5c064653c4
--- /dev/null
+++ b/py/mpconfig.h
@@ -0,0 +1,13 @@
+// This file contains default configuration settings for MicroPython.
+// You can override any of these options using mpconfigport.h file located
+// in a directory of your port.
+
+#include <mpconfigport.h>
+
+// Any options not explicitly set in mpconfigport.h will get default
+// values below.
+
+// Whether to collect memory allocation stats
+#ifndef MICROPY_MEM_STATS
+#define MICROPY_MEM_STATS (1)
+#endif
diff --git a/stm/Makefile b/stm/Makefile
index 018d31f491ae6cf0ade51970ef2b9c05923eb5e8..d6c77e2bd7258b5f1317ca48998463c3b42ced8c 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -187,7 +187,7 @@ $(BUILD)/%.o: $(PYSRC)/%.s
 $(BUILD)/%.o: $(PYSRC)/%.S
 	$(CC) $(CFLAGS) -c -o $@ $<
 
-$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h
+$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
diff --git a/stm/mpconfig.h b/stm/mpconfigport.h
similarity index 96%
rename from stm/mpconfig.h
rename to stm/mpconfigport.h
index 1f9529e11ba8df1afdb692e129061534878b9870..4cea332f3977f5c3206d5ee85523c5e8a08684e8 100644
--- a/stm/mpconfig.h
+++ b/stm/mpconfigport.h
@@ -1,3 +1,5 @@
+#include <stdint.h>
+
 // options to control how Micro Python is built
 
 #define MICROPY_ENABLE_FLOAT        (1)
diff --git a/unix/Makefile b/unix/Makefile
index 271cf226542931e4636133bf3495f08aa8f000f2..fd5b6b43e0fc0928f7eb5be508e7fbaaa3fedcbb 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -79,7 +79,7 @@ $(BUILD)/%.o: %.c
 $(BUILD)/%.o: $(PYSRC)/%.S
 	$(CC) $(CFLAGS) -c -o $@ $<
 
-$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h
+$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
@@ -92,7 +92,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
 $(BUILD)/vm.o: $(PYSRC)/vm.c
 	$(CC) $(CFLAGS) -O3 -c -o $@ $<
 
-$(BUILD)/main.o: mpconfig.h
+$(BUILD)/main.o: mpconfigport.h
 $(BUILD)/parse.o: $(PYSRC)/grammar.h
 $(BUILD)/compile.o: $(PYSRC)/grammar.h
 $(BUILD)/emitcpy.o: $(PYSRC)/emit.h
diff --git a/unix/mpconfig.h b/unix/mpconfigport.h
similarity index 100%
rename from unix/mpconfig.h
rename to unix/mpconfigport.h