It is out of memory because it hold all the transaction in memory and only send it over to the database when you call executeBatch.
If you don't need it to be atomic and would like the get better performance, you can keep a counter and call executeBatch every n number of records.