I've been doing some profiling and digging through the code to see what's going on with memory; I've got a test program which generates about 60 columns of dummy data and it throws OOM Exceptions when I try to generate 100,000 rows. This is on Windows 10, 64-bit, with 8 GB of memory.
It's possible that the underlying OpenXML libraries from Microsoft are using XMLSerializer, but that's not something that ClosedXML can do much about. As far as I can tell, ClosedXML doesn't use XMLSerializer directly.
The bulk of the problem does seem to be the number of XLCell objects allocated. Reducing their size would help, but I don't see an easy way of doing that. Every single XLCell ultimately allocates its own XLStyle object (which in turn has an Alignment, Border, Fill, etc.); the library doesn't re-use XLStyle objects across multiple cells. It would require a pretty significant change to the style design to make that re-use happen.
A little bit of breathing room would be gained by removing the _trimmedAddress and _columnLetter members from XLAddress; these are being used to cache values which can be computed. Removing them will reduce the memory pressure - since every XLCell has and XLAddress, those two cached values are being stored for every single cell allocated, which adds up when we're talking about hundreds of thousands (or even millions) of cells.
It's possible that the underlying OpenXML libraries from Microsoft are using XMLSerializer, but that's not something that ClosedXML can do much about. As far as I can tell, ClosedXML doesn't use XMLSerializer directly.
The bulk of the problem does seem to be the number of XLCell objects allocated. Reducing their size would help, but I don't see an easy way of doing that. Every single XLCell ultimately allocates its own XLStyle object (which in turn has an Alignment, Border, Fill, etc.); the library doesn't re-use XLStyle objects across multiple cells. It would require a pretty significant change to the style design to make that re-use happen.
A little bit of breathing room would be gained by removing the _trimmedAddress and _columnLetter members from XLAddress; these are being used to cache values which can be computed. Removing them will reduce the memory pressure - since every XLCell has and XLAddress, those two cached values are being stored for every single cell allocated, which adds up when we're talking about hundreds of thousands (or even millions) of cells.