We can get away with another 4GB of random access header (I tested with this), which pushes the total to 20GB. But 8GB would put us at 24GB, leaving only 8 for block/prevout population and validation table searches. Even if that was sufficient, building the table is likely a major cost, especially since the final stage requires a total ordering by block. So to confirm a block we would have to construct all prior filters in order, and that means even for all milestone blocks (filters are cumulative).