A common practice to save power and energy in embedded systems is to "put to sleep" or disable parts of the hardware. The memory system consumes a significant portion of the energy budget of the overall system, so it is a natural target for energy optimization techniques. The principle of software locality makes the memory subsystem an even better choice, since all memory blocks but the ones immediately required can be disabled at any given time. This opportunity is the motivation for developing energy optimization techniques to dynamically and selectively control the power state of the different parts of the memory system. This dissertation develops a set of algorithms and techniques that can be organized into a hardware/software co-development tool to help designers apply the selective powering of memory blocks to minimize energy consumption. In data driven embedded systems, most of the data memory is used either by global static variables or by dynamic variables. Although techniques already exist for energy-aware allocation of global static arrays under certain constraints, very little work has focused on dynamic variables, which are actually more important to event driven/data driven embedded systems than their static counterparts. This dissertation addresses this gap, and extends and consolidates previous allocation techniques in a unique framework. A formal model for memory energy optimization for dynamic and global static variables and efficient algorithms for energy aware allocation of variables to memory are presented. Dependencies between generic code and data are uncovered, and this information is exploited to fine-tune a system. A framework is presented for retrieving this profile information which is then used to design energy aware allocation algorithms for dynamic variables, including heuristics for segmentation and control of the memory heap. By working at the assembly code level, these techniques can be integrated into any compiler regardless of the source language. The proposed techniques were implemented and tested against data intensive benchmarks, and experimental results indicate significant savings of up to 50% in the memory system energy consumption.