Yes, it is good practice security-wise to overwrite data that is particularly sensitive when the data is no longer necessary, i.e. as part of an object destructor (either an explicit destructor provided by the language or an action that the program takes before deallocating the object). It is even good practice to overwrite data that isn't in itself sensitive, for example to zero out pointer fields in a data structure that goes out of use, and also zero out pointers when the object they point to is freed even if you know you aren't going to use that field anymore.
One reason to do this is in case the data leaks through external factors such as an exposed core dump, a stolen hibernation image, a compromised server allowing a memory dump of running processes, etc. Physical attacks where an attacker extracts the RAM sticks and makes use of data remanence are rarely a concern except on laptop computers and perhaps mobile devices such as phones (where the bar is higher because the RAM is soldered), and even then mostly in targeted scenarios only. Remanence of overwritten values is not a concern: it would take very expensive hardware to probe inside a RAM chip to detect any lingering microscopic voltage difference that might be influenced by an overwritten value. If you're worried about physical attacks on the RAM, a bigger concern would be to ensure that the data is ovewritten in RAM and not just in the CPU cache. But, again, that's usually a very minor concern.
The most important reason to overwrite stale data is as a defense against program bugs that cause uninitialized memory to be used, such as the infamous Heartbleed. This goes beyond sensitive data because the risk is not limited to a leak of the data: if there is a software bug that causes a pointer field to be dereferenced without having been initialized, the bug is both less prone to exploitation and easier to trace if the field contains all-bits-zero than if it potentially points to a valid but meaningless memory location.
Beware that good compilers will optimize the zeroing out if they detect that the value is no longer used. You may need to use some compiler-specific trick to make the compiler believe that the value remains in use and thus generate the zeroing out code.
In many languages with automatic management, objects can be moved in memory without notice. This means that it's hard to control leaks of stale data, unless the memory manager itself erases unused memory (they often don't, for performance). On the plus side, external leaks are usually all you have to worry about, since high-level languages tend to preclude the use of uninitialized memory (beware of string creation functions in languages with mutable strings).
By the way, I wrote “zero out” above. You can use a bit pattern other than all zeros; all-zeros has the advantage that it's an invalid pointer in most environments. A bit pattern that you know is an invalid pointers but that is more distinctive can be helpful in debugging.
A lot of security standards mandate the erasure of sensitive data such as keys. For example, the FIPS 140-2 standard for cryptographic modules requires it even at the lowest assurance level, which apart from that only requires functional compliance and not resistance against attacks.
mlock
the memory (to ensure it's not written to swap),mprotect
the page so that it's read-only once the secret data has been initialized (also possibly to mark the page as non-accessible at all except in the small windows in which you intend to access it), to have a "canary" value written to memory immediately after the secret to detect during dealloc if it's been overwritten by an overflow, and to allocate extra non-accessible guard pages before and after the secret to SEGV on overflow and underflow.volatile
, because they don't change the result of executing the code (the value is not used anywhere).