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: 
Here is an example from Netty which does something similar: [MemoryAwareThreadPoolExecutor](http://grepcode.com/file/repo1.maven.org/maven2/org.jboss.netty/netty/3.0.0.CR1/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java). Guava's [cache class](https://code.google.com/p/guava-libraries/wiki/CachesExplained) has also a size based eviction. You could look at these sources and copy what they are doing. In particular, Here is how Netty is [estimating object sizes](http://grepcode.com/file/repo1.maven.org/maven2/com.ning/metrics.goodwill-access/0.0.10/org/jboss/netty/util/DefaultObjectSizeEstimator.java?av=h#DefaultObjectSizeEstimator). In essence, you'd estimate the size of the objects you generate in the method and keep a count.

Getting overall memory information (like how much heap is available/used) will help you decide how much memory usage to allocate to the method, but not to track how much memory was used by the individual method calls.

Having said that, it's very rare that you legitimately need this. In most cases, capping the memory usage by limiting how many objects can be there at a given point (e.g. by using a bounded queue) is good enough and is much, much simpler to implement.
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;
}

```