>Now, considering that the application crashes when I make 300,000 cats, wouldn't that be a problem in real life situations
Well designed applications avoid that kind of situation by dividing data sets into manageable pieces. Two good examples are streaming and persistence. If you only need one item at a time then you can stream through the items one by one either by generating or retrieving them, processing them, and then reclaiming or reusing the memory for the next item. If you don't
have to have RAM-speed access for every item in the entire set all at once, you can persist most of the set to disk and keep a cache of a much smaller set for quick access.
If you
do have to have RAM-speed access for every item in a data set all at once and the size breaks your application, you can start looking for another job because you'll get fired with solutions like that.
