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.
The easiest way to estimate memory usage is to use methods from `Runtime` class.
--------------------------------------------------------------------------------

**I suggest not to rely on it, but use it only for approximate estimations. Ideally you should only log this information and analyze it on your own, without using it for automation of your test or code.**

Probably it isn't very reliable, but in closed environment like unit test it may give you estimate close to reality.  

Especially there is no guarantee that after calling `System.gc()` garbage collector will run when we expect it (it is only a suggestion for GC), there are precision limitations of the `freeMemory` method described there: <https://stackoverflow.com/a/17376879/1673775> and there might be more caveats.

### Solution:

```
private static final long BYTE_TO_MB_CONVERSION_VALUE = 1024 * 1024;

@Test
public void memoryUsageTest() {
  long memoryUsageBeforeLoadingData = getCurrentlyUsedMemory();
  log.debug("Used memory before loading some data: " + memoryUsageBeforeLoadingData + " MB");
  List<SomeObject> somethingBigLoadedFromDatabase = loadSomethingBigFromDatabase();
  long memoryUsageAfterLoadingData = getCurrentlyUsedMemory();
  log.debug("Used memory after loading some data: " + memoryUsageAfterLoadingData + " MB");
  log.debug("Difference: " + (memoryUsageAfterLoadingData - memoryUsageBeforeLoadingData) + " MB");
  someOperations(somethingBigLoadedFromDatabase);
}

private long getCurrentlyUsedMemory() {
  System.gc();
  return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / BYTE_TO_MB_CONVERSION_VALUE;
}

```