An import job that works fine in testing dies with an OutOfMemoryError in production on a file with five million rows, using `List<Integer>` to hold one column. Nothing in the code looks wasteful. What's actually happening, and how would you fix it?
List<Integer> looks like a list of numbers, but generics can't hold primitives — every element is a full Integer object, not a raw int. Five million ints packed contiguously is about 19 MB; five million boxed Integer objects, each with its own object header, plus the ArrayList's backing array of references pointing at them, comes to roughly 95 MB — five times more for identical data, and nothing in the source code signals that cost. The test file is small enough that the difference is invisible; the production file is five million rows, and the boxing multiplies the memory five times over until the process runs out of heap. The fix is to stream the data instead of loading it all, or to use a primitive-specialised structure (an int[], or a library's primitive collection) instead of a boxed List<Integer>, so the five million numbers cost 19 MB instead of 95.