Question: If I have :

* An object A containing a `List<B>`
* All objects B in my `List<B>` containing a `List<C>`
* all objects C in my `List<C>` containing a `List<D>`
etc...

How the memory is managed ? all "linked" objects (B,C,D...) are instanciated and put in memory when the object A is instanciated ?

Answer: 
Each time you call `new()` the memory required for the corresponding object is taken from the heap.

As you most often **start** by creating an empty list - only the memory required for that thing is requested.

In other words: there is no way to create the "complete" structure in one shot. It makes no difference if you do:

```
List<List<String>> strings = new ArrayList<>();

```

or

```
List<Number> numbers = new ArrayList<>();

```

The amount of memory that is allocated on the heap is the *same* for both of these instructions! Because in *both* cases **one** new object is created (that ArrayList instance).
The statement `List<String> strings = new ArrayList<>();` only allocates heap space for the list itsself, the list only stores **references** to the object it contains, it doesn't contain the objects themselves.

Note that an ArrayList is using an array as it's internal structure (you might have guessed that), so the constructor is basically allocating an array of an initial size. For creating huge ArrayLists, you should pre-allocate space to be more efficient, e.g. `List<String> strings = new ArrayList<>(2000);` preallocates space for 2000 String references.