Really interesting question. I have dealt with this in the past, and I hope to share with you!
- You should implement enhanced memory pooling with object pools. Use a more sophisticated memory pool mechanism that recycles objects efficiently.
- What I often used to detect data races at runtime is by using ThreadSanitizer (which is a part of LLVM) :). This will help you by a lot!