  Java is the "go-to" programming language choice for developing scalable
enterprise cloud applications. In such systems, even a few percent CPU time
savings can offer a significant competitive advantage and cost saving. Although
performance tools abound in Java, those that focus on the data locality in the
memory hierarchy are rare.
  In this paper, we present DJXPerf, a lightweight, object-centric memory
profiler for Java, which associates memory-hierarchy performance metrics (e.g.,
cache/TLB misses) with Java objects. DJXPerf uses statistical sampling of
hardware performance monitoring counters to attribute metrics to not only
source code locations but also Java objects. DJXPerf presents Java object
allocation contexts combined with their usage contexts and presents them
ordered by the poor locality behaviors. DJXPerf's performance measurement,
object attribution, and presentation techniques guide optimizing object
allocation, layout, and access patterns. DJXPerf incurs only ~8% runtime
overhead and ~5% memory overhead on average, requiring no modifications to
hardware, OS, Java virtual machine, or application source code, which makes it
attractive to use in production. Guided by DJXPerf, we study and optimize a
number of Java and Scala programs, including well-known benchmarks and
real-world applications, and demonstrate significant speedups.
