Question: Assuming I have a class that does some heavy processing, operating with several collections. What I want to do is to make sure that such operation can't lead to out-of-memory or even better I want to set a threshold of how much memory it can use.

```
class MyClass()
{
   public void myMethod()
   {
      for(int i=0; i<10000000; i++)
      {
         // Allocate some memory, may be several collections
      }
   }
}

class MyClassTest
{
   @Test
   public void myMethod_makeSureMemoryFootprintIsNotBiggerThanMax()
   {
      new MyClass().myMethod(); 
      // How do I measure amount of memory it may try to allocate?
   }
}

```

What is the right approach to do this? Or this is not possible/not feasible?

Answer: 
To measure current memory usage use :

`Runtime.getRuntime().freeMemory()` ,
`Runtime.getRuntime().totalMemory()`

Here is a good example:
[get OS-level system information](https://stackoverflow.com/questions/25552/using-java-to-get-os-level-system-information)

But this measurement is not precise but it can give you much information.
Another problem is with `GC` which is unpredictable.
This question is a bit tricky, due to the way in which Java can allocate a lot of short-lived objects during processing, which will subsequently be collected during garbage collection. In the accepted answer, we cannot say with any certainty that garbage collection has been run at any given time. Even if we introduce a loop structure, with multiple `System.gc()` calls, garbage collection might run in between our method calls.

A better way is to instead use some variation of what is suggested in <https://cruftex.net/2017/03/28/The-6-Memory-Metrics-You-Should-Track-in-Your-Java-Benchmarks.html>, where `System.gc()` is triggered but we also wait for the reported GC count to increase:

```
long getGcCount() {
    long sum = 0;
    for (GarbageCollectorMXBean b : ManagementFactory.getGarbageCollectorMXBeans()) {
        long count = b.getCollectionCount();
        if (count != -1) { sum += count; }
    }
    return sum;
}

long getReallyUsedMemory() {
    long before = getGcCount();
    System.gc();
    while (getGcCount() == before);
    return getCurrentlyAllocatedMemory();
}

long getCurrentlyAllocatedMemory() {
    final Runtime runtime = Runtime.getRuntime();
    return (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024);
}

```

This still gives only an approximation of the memory actually allocated by your code at a given time, but the value is typically much closer to what one would usually be interested in.