  Many performance inefficiencies such as inappropriate choice of algorithms or
data structures, developers' inattention to performance, and missed compiler
optimizations show up as wasteful memory operations. Wasteful memory operations
are those that produce/consume data to/from memory that may have been avoided.
We present, JXPerf, a lightweight performance analysis tool for pinpointing
wasteful memory operations in Java programs. Traditional byte-code
instrumentation for such analysis (1) introduces prohibitive overheads and (2)
misses inefficiencies in machine code generation. JXPerf overcomes both of
these problems. JXPerf uses hardware performance monitoring units to sample
memory locations accessed by a program and uses hardware debug registers to
monitor subsequent accesses to the same memory. The result is a lightweight
measurement at machine-code level with attribution of inefficiencies to their
provenance: machine and source code within full calling contexts. JXPerf
introduces only 7% runtime overhead and 7% memory overhead making it useful in
production. Guided by JXPerf, we optimize several Java applications by
improving code generation and choosing superior data structures and algorithms,
which yield significant speedups.
