Memory Management What You Need To Know When Moving to Java 8 Todd Rader, Architect / Sales Engineer AppDynamics
Market Leadership 175% Bookings Growth 2013 1000+ Customers OUR PLATFORM Website download Rapid Time to Value Low cost of ownership $ Enterprise adoption Scalable - largest APM deployments On-Premise, SaaS, Hybrid No professional Services 84 Net Promoter Score OUR APPDYNAMICS Copyright © 2014 AppDynamics. All rights reserved. 2
Agenda • Memory Basics • …with a dive into metaspace • Fun With Garbage Collectors • GC bake-off • Summary/Conclusions • Q&A Copyright © 2014 AppDynamics. All rights reserved. 3
Memory Basics: Types of Memory STACK • Each thread has its own call stack • Adjust with -Xss • 64-bit JVMs need more stack size (8-byte references) • Default stack size: ???? Java7, jdk1.7.0_51, 64-bit on MacOS 10.9.6 • Call depth before StackOverflowError: 10,827 (consistently) Java8, jdk1.8.0_05, 64-bit on MacOS 10.9.6 • Call depth before StackOverflowError: 20,000-ish (huh?) Copyright © 2014 AppDynamics. All rights reserved. 4
Stack (cont’d) FUN WITH NUMBERS…. • With Java8 default stack size, call depth = 20,000-ish • Using –Xss1024k, same result (SO: default –Xss=1024k) • Using –XX:ThreadStackSize=1024, same result (- XX:ThreadStackSize is another way of expressing –Xss) Okay, but… • -Xss512k result: 9000-ish • Not quite linear! Need more memory space? Use a smaller –Xss value! • 200 threads * 512kb/thread = 100 MB saved! • What is your true stack size requirement? Copyright © 2014 AppDynamics. All rights reserved. 5
Memory Basics: Types of Memory (cont’d) HEAP • Eden/New vs. Survivor vs. Old/Tenured • “Ideal Object Death Rate” • Eden >> Old >> Survivor Copyright © 2014 AppDynamics. All rights reserved. 6
Heap (cont’d) HEAP • What is your object survival demography? • Caching! • Find out with: • -XX:+PrintGCDetails • -XX:+PrintTenuringDistribution • -XX:+PrintGCTimestamps • Adjust with: • -XX:NewRatio=n – Example: NewRatio=2  (oldGenSize) = 2 * (newGenSize) • -XX:NewSize=n (minimum) • -XX:MaxNewSize=n • -XX:MinFreeHeapRatio=n • -XX:MaxFreeHeapRatio=n Copyright © 2014 AppDynamics. All rights reserved. 7
Heap: Java 6 HotSpot Copyright © 2014 AppDynamics. All rights reserved. 8
Memory Basics: Types of Memory (cont’d) META • PermGen in Java 6 • PermGen (sort of) in Java 7 • Metaspace in Java 8 while (true) { int length = rnd.nextInt(100); StringBuilder builder = new StringBuilder(); String chars = "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; i++) { builder.append(chars.charAt(rnd.nextInt(chars.length()))); } interned.add(builder.toString().intern()); } What happens when this code is run? Copyright © 2014 AppDynamics. All rights reserved. 9
Running the code… JAVA 6 Exception in thread "main" java.lang.OutOfMemoryError: PermGen space • …in about 8 seconds! JAVA 7 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space • …and it takes a long time to happen! JAVA 8 • Similar result as with Java 7 Copyright © 2014 AppDynamics. All rights reserved. 10
What happened??? JAVA 6 PermGen contains: • Class meta data • Interned strings JAVA 7 • Interned strings moved to Metaspace JAVA 8 • Class meta data also moved to Metaspace Copyright © 2014 AppDynamics. All rights reserved. 11
Metaspace REPLACEMENT FOR PERMGEN • NOT JVM memory – native memory! • BEA/Oracle JRockit • IBM JVM SOME NEW STARTUP FLAGS • -XX:MetaSpaceSize=n (initial size) • -XX:MaxMetaSpaceSize=n • -XX:MaxMetaspaceExpansion=n • -XX:MaxMetaspaceFreeRatio=n • No default values for size! Max metaspace size is unlimited :-0 • Say goodbye to PermGen problems……right? Right? Copyright © 2014 AppDynamics. All rights reserved. 12
More Metaspace OBSOLETES SOME OLD STARTUP FLAGS • All of the “-XX:*Perm*” flags NEW MEMORY POOL OBJECTS • No more matching on “Perm” for pool name Copyright © 2014 AppDynamics. All rights reserved. 13
What does this mean? NO MORE OOM/PERMGEN • But metaspace errors don’t go away  • Monitor metaspace, not PermGen • Use –XX:MaxMetaSpaceSize? • No  you will never run out of metaspace • …but your use of native memory can grow unbounded! • Yes  you merely replace “OutOfMemory: PermGen space” with “OutOfMemory: Metaspace” MONITOR METASPACE • Apps that leak metadata will still leak metadata • Gobbling up metaspace affects the entire system, not just the JVM • Remember: native memory! Copyright © 2014 AppDynamics. All rights reserved. 14
Monitoring Metaspace COMMERCIAL SOLUTIONS • Expect (demand!) metaspace monitoring support to go along with Java 8 support JAVA MANAGEMENT BEANS • Update any querying of MBeans to search for Metaspace memory pool instead of PermGen pools. JVISUALVM • Metaspace monitoring supported • …at least in the jvisualvm that is bundled with Jdk1.8.0_05 on MacOS! Copyright © 2014 AppDynamics. All rights reserved. 15
Memory Basics: Types of Memory (cont’d) DIRECT • sun.misc.Unsafe • Used by the JDK (nio classes, for example) • Out of the scope of this talk! Copyright © 2014 AppDynamics. All rights reserved. 16
Let’s talk garbage… PARALLEL GC • Default on Java 7, Java 8 • ParNewGC is the default on Java 6 • Does parallel compaction in Java 6 and 7 • -XX:+UseParallelOldGC option in Java 5 CONCURRENT MARK AND SWEEP GC • NOT compacting! • Can be prone to fragmentation of old gen •  very bad full GCs result G1GC • Only use after jdk1.7.0_u4! • “Experimental” in previous releases Copyright © 2014 AppDynamics. All rights reserved. 17
The GC Bake-off GC KILLER PROGRAM • Allocates lots of java.lang.Objects • Allocates fewer long Strings • Keeps objects around for varying lengths of times • Checks heap memory availability • When low, thousands of memory references are let go of • No GC tuning options used • 15-minute runs (killed with Ctrl-C) • Java 7 vs. Java 8 Copyright © 2014 AppDynamics. All rights reserved. 18
Java 7, Parallel GC Copyright © 2014 AppDynamics. All rights reserved. 19
Java 7, Parallel GC HIGHLIGHTS • No “-XX” option to enable (default) • Heap usage varied between 1500-2750 MB • Reasonable time spent in GC (1.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 20
Java 7, ConcMarkSweepGC Copyright © 2014 AppDynamics. All rights reserved. 21
Java 7, ConcMarkSweepGC HIGHLIGHTS • Enabled with –XX:+UseConcMarkSweepGC • Heap usage held steady around 2000 MB • Huge amount of time spent in GC (24 seconds/minute!) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 22
Java 7, G1GC Copyright © 2014 AppDynamics. All rights reserved. 23
Java 7, G1GC HIGHLIGHTS • Enabled with –XX:+UseG1GC • Heap usage varied between 750-2800 MB • Very reasonable time spent in GC (0.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 24
The winner for Java 7 G1! • Less time spent in GC • Heap usage max barely more than max using Parallel • CMS max heap usage was only 2000 • CMS min was also near 2000 (very steady) • Heap usage min best of all three • No major collections • BUT: • Remember, no GC tuning parameters were used • DO NOT USE G1GC before jdk1.7.0_04 • “Experimental” in prior releases Copyright © 2014 AppDynamics. All rights reserved. 25
Java 8, Parallel GC Copyright © 2014 AppDynamics. All rights reserved. 26
Java 8, Parallel GC HIGHLIGHTS • Incrementally worse than ParallelGC on Java 7 • Higher max heap (2950 vs. 2750) • Higher min heap (1700MB vs. 1500MB) • Roughly the same GC time (1.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 27
Java 8, ConcMarkSweepGC Copyright © 2014 AppDynamics. All rights reserved. 28
Java 8, ConcMarkSweepGC HIGHLIGHTS • Just……lousy • HUGE amount of initial time spent in gc • 55 seconds/minute! • Heap usage steadily declined • From 3000MB to 2000MB • With all that time spent, you’d think a major collection would be avoided • You’d be wrong  • The only run with a major collection Copyright © 2014 AppDynamics. All rights reserved. 29
Java 8, G1GC Copyright © 2014 AppDynamics. All rights reserved. 30
Java 8, G1GC HIGHLIGHTS • Incrementally worse than G1/Java 7 • Heap usage max 2850MB vs. 2800MB • GC time .8 seconds/minute vs. .6 seconds/minute • No major collections Copyright © 2014 AppDynamics. All rights reserved. 31
The winner for Java 8, and overall G1 AGAIN! • CMS not even close • G1 on Java 7 overall winner • Caveats: • No GC tuning parameters used • Heap-only: very little metadata memory used • MacOS 10.9.4 (Maverick’s) • 2.8 GHz Intel Core i7 processor • 16 GB 1600 MHz memory • Java 7: jdk 1.7.0_51 for MacOS • Java 8: jdk 1.8.0_05 for MacOS Copyright © 2014 AppDynamics. All rights reserved. 32
GC Tuning OUT OF SCOPE  • 600+ “-XX:” options • 83 for CMS in Java 7 • 82 for CMS in Java 8 • No love for CMSTriggerPermRatio! • 24 for G1 in Java 7 and 8 • Too many to cover! Copyright © 2014 AppDynamics. All rights reserved. 33
Summary • Know your object demography • Monitor your metaspace • Interned strings • Class metadata • Research the best GC • Watch out for outdated information • G1GC tests before jdk1.7.0_04 • Re-think CMS GC? • Un-tuned CMS results far worse Copyright © 2014 AppDynamics. All rights reserved. 34
FREE trial available: www.appdynamics.com
Thank you

Memory Management: What You Need to Know When Moving to Java 8

  • 1.
    Memory Management What YouNeed To Know When Moving to Java 8 Todd Rader, Architect / Sales Engineer AppDynamics
  • 2.
    Market Leadership 175% Bookings Growth2013 1000+ Customers OUR PLATFORM Website download Rapid Time to Value Low cost of ownership $ Enterprise adoption Scalable - largest APM deployments On-Premise, SaaS, Hybrid No professional Services 84 Net Promoter Score OUR APPDYNAMICS Copyright © 2014 AppDynamics. All rights reserved. 2
  • 3.
    Agenda • Memory Basics •…with a dive into metaspace • Fun With Garbage Collectors • GC bake-off • Summary/Conclusions • Q&A Copyright © 2014 AppDynamics. All rights reserved. 3
  • 4.
    Memory Basics: Typesof Memory STACK • Each thread has its own call stack • Adjust with -Xss • 64-bit JVMs need more stack size (8-byte references) • Default stack size: ???? Java7, jdk1.7.0_51, 64-bit on MacOS 10.9.6 • Call depth before StackOverflowError: 10,827 (consistently) Java8, jdk1.8.0_05, 64-bit on MacOS 10.9.6 • Call depth before StackOverflowError: 20,000-ish (huh?) Copyright © 2014 AppDynamics. All rights reserved. 4
  • 5.
    Stack (cont’d) FUN WITHNUMBERS…. • With Java8 default stack size, call depth = 20,000-ish • Using –Xss1024k, same result (SO: default –Xss=1024k) • Using –XX:ThreadStackSize=1024, same result (- XX:ThreadStackSize is another way of expressing –Xss) Okay, but… • -Xss512k result: 9000-ish • Not quite linear! Need more memory space? Use a smaller –Xss value! • 200 threads * 512kb/thread = 100 MB saved! • What is your true stack size requirement? Copyright © 2014 AppDynamics. All rights reserved. 5
  • 6.
    Memory Basics: Typesof Memory (cont’d) HEAP • Eden/New vs. Survivor vs. Old/Tenured • “Ideal Object Death Rate” • Eden >> Old >> Survivor Copyright © 2014 AppDynamics. All rights reserved. 6
  • 7.
    Heap (cont’d) HEAP • Whatis your object survival demography? • Caching! • Find out with: • -XX:+PrintGCDetails • -XX:+PrintTenuringDistribution • -XX:+PrintGCTimestamps • Adjust with: • -XX:NewRatio=n – Example: NewRatio=2  (oldGenSize) = 2 * (newGenSize) • -XX:NewSize=n (minimum) • -XX:MaxNewSize=n • -XX:MinFreeHeapRatio=n • -XX:MaxFreeHeapRatio=n Copyright © 2014 AppDynamics. All rights reserved. 7
  • 8.
    Heap: Java 6HotSpot Copyright © 2014 AppDynamics. All rights reserved. 8
  • 9.
    Memory Basics: Typesof Memory (cont’d) META • PermGen in Java 6 • PermGen (sort of) in Java 7 • Metaspace in Java 8 while (true) { int length = rnd.nextInt(100); StringBuilder builder = new StringBuilder(); String chars = "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; i++) { builder.append(chars.charAt(rnd.nextInt(chars.length()))); } interned.add(builder.toString().intern()); } What happens when this code is run? Copyright © 2014 AppDynamics. All rights reserved. 9
  • 10.
    Running the code… JAVA6 Exception in thread "main" java.lang.OutOfMemoryError: PermGen space • …in about 8 seconds! JAVA 7 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space • …and it takes a long time to happen! JAVA 8 • Similar result as with Java 7 Copyright © 2014 AppDynamics. All rights reserved. 10
  • 11.
    What happened??? JAVA 6 PermGencontains: • Class meta data • Interned strings JAVA 7 • Interned strings moved to Metaspace JAVA 8 • Class meta data also moved to Metaspace Copyright © 2014 AppDynamics. All rights reserved. 11
  • 12.
    Metaspace REPLACEMENT FOR PERMGEN •NOT JVM memory – native memory! • BEA/Oracle JRockit • IBM JVM SOME NEW STARTUP FLAGS • -XX:MetaSpaceSize=n (initial size) • -XX:MaxMetaSpaceSize=n • -XX:MaxMetaspaceExpansion=n • -XX:MaxMetaspaceFreeRatio=n • No default values for size! Max metaspace size is unlimited :-0 • Say goodbye to PermGen problems……right? Right? Copyright © 2014 AppDynamics. All rights reserved. 12
  • 13.
    More Metaspace OBSOLETES SOMEOLD STARTUP FLAGS • All of the “-XX:*Perm*” flags NEW MEMORY POOL OBJECTS • No more matching on “Perm” for pool name Copyright © 2014 AppDynamics. All rights reserved. 13
  • 14.
    What does thismean? NO MORE OOM/PERMGEN • But metaspace errors don’t go away  • Monitor metaspace, not PermGen • Use –XX:MaxMetaSpaceSize? • No  you will never run out of metaspace • …but your use of native memory can grow unbounded! • Yes  you merely replace “OutOfMemory: PermGen space” with “OutOfMemory: Metaspace” MONITOR METASPACE • Apps that leak metadata will still leak metadata • Gobbling up metaspace affects the entire system, not just the JVM • Remember: native memory! Copyright © 2014 AppDynamics. All rights reserved. 14
  • 15.
    Monitoring Metaspace COMMERCIAL SOLUTIONS •Expect (demand!) metaspace monitoring support to go along with Java 8 support JAVA MANAGEMENT BEANS • Update any querying of MBeans to search for Metaspace memory pool instead of PermGen pools. JVISUALVM • Metaspace monitoring supported • …at least in the jvisualvm that is bundled with Jdk1.8.0_05 on MacOS! Copyright © 2014 AppDynamics. All rights reserved. 15
  • 16.
    Memory Basics: Typesof Memory (cont’d) DIRECT • sun.misc.Unsafe • Used by the JDK (nio classes, for example) • Out of the scope of this talk! Copyright © 2014 AppDynamics. All rights reserved. 16
  • 17.
    Let’s talk garbage… PARALLELGC • Default on Java 7, Java 8 • ParNewGC is the default on Java 6 • Does parallel compaction in Java 6 and 7 • -XX:+UseParallelOldGC option in Java 5 CONCURRENT MARK AND SWEEP GC • NOT compacting! • Can be prone to fragmentation of old gen •  very bad full GCs result G1GC • Only use after jdk1.7.0_u4! • “Experimental” in previous releases Copyright © 2014 AppDynamics. All rights reserved. 17
  • 18.
    The GC Bake-off GCKILLER PROGRAM • Allocates lots of java.lang.Objects • Allocates fewer long Strings • Keeps objects around for varying lengths of times • Checks heap memory availability • When low, thousands of memory references are let go of • No GC tuning options used • 15-minute runs (killed with Ctrl-C) • Java 7 vs. Java 8 Copyright © 2014 AppDynamics. All rights reserved. 18
  • 19.
    Java 7, ParallelGC Copyright © 2014 AppDynamics. All rights reserved. 19
  • 20.
    Java 7, ParallelGC HIGHLIGHTS • No “-XX” option to enable (default) • Heap usage varied between 1500-2750 MB • Reasonable time spent in GC (1.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 20
  • 21.
    Java 7, ConcMarkSweepGC Copyright© 2014 AppDynamics. All rights reserved. 21
  • 22.
    Java 7, ConcMarkSweepGC HIGHLIGHTS •Enabled with –XX:+UseConcMarkSweepGC • Heap usage held steady around 2000 MB • Huge amount of time spent in GC (24 seconds/minute!) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 22
  • 23.
    Java 7, G1GC Copyright© 2014 AppDynamics. All rights reserved. 23
  • 24.
    Java 7, G1GC HIGHLIGHTS •Enabled with –XX:+UseG1GC • Heap usage varied between 750-2800 MB • Very reasonable time spent in GC (0.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 24
  • 25.
    The winner forJava 7 G1! • Less time spent in GC • Heap usage max barely more than max using Parallel • CMS max heap usage was only 2000 • CMS min was also near 2000 (very steady) • Heap usage min best of all three • No major collections • BUT: • Remember, no GC tuning parameters were used • DO NOT USE G1GC before jdk1.7.0_04 • “Experimental” in prior releases Copyright © 2014 AppDynamics. All rights reserved. 25
  • 26.
    Java 8, ParallelGC Copyright © 2014 AppDynamics. All rights reserved. 26
  • 27.
    Java 8, ParallelGC HIGHLIGHTS • Incrementally worse than ParallelGC on Java 7 • Higher max heap (2950 vs. 2750) • Higher min heap (1700MB vs. 1500MB) • Roughly the same GC time (1.6 seconds/minute) • No major collections Copyright © 2014 AppDynamics. All rights reserved. 27
  • 28.
    Java 8, ConcMarkSweepGC Copyright© 2014 AppDynamics. All rights reserved. 28
  • 29.
    Java 8, ConcMarkSweepGC HIGHLIGHTS •Just……lousy • HUGE amount of initial time spent in gc • 55 seconds/minute! • Heap usage steadily declined • From 3000MB to 2000MB • With all that time spent, you’d think a major collection would be avoided • You’d be wrong  • The only run with a major collection Copyright © 2014 AppDynamics. All rights reserved. 29
  • 30.
    Java 8, G1GC Copyright© 2014 AppDynamics. All rights reserved. 30
  • 31.
    Java 8, G1GC HIGHLIGHTS •Incrementally worse than G1/Java 7 • Heap usage max 2850MB vs. 2800MB • GC time .8 seconds/minute vs. .6 seconds/minute • No major collections Copyright © 2014 AppDynamics. All rights reserved. 31
  • 32.
    The winner forJava 8, and overall G1 AGAIN! • CMS not even close • G1 on Java 7 overall winner • Caveats: • No GC tuning parameters used • Heap-only: very little metadata memory used • MacOS 10.9.4 (Maverick’s) • 2.8 GHz Intel Core i7 processor • 16 GB 1600 MHz memory • Java 7: jdk 1.7.0_51 for MacOS • Java 8: jdk 1.8.0_05 for MacOS Copyright © 2014 AppDynamics. All rights reserved. 32
  • 33.
    GC Tuning OUT OFSCOPE  • 600+ “-XX:” options • 83 for CMS in Java 7 • 82 for CMS in Java 8 • No love for CMSTriggerPermRatio! • 24 for G1 in Java 7 and 8 • Too many to cover! Copyright © 2014 AppDynamics. All rights reserved. 33
  • 34.
    Summary • Know yourobject demography • Monitor your metaspace • Interned strings • Class metadata • Research the best GC • Watch out for outdated information • G1GC tests before jdk1.7.0_04 • Re-think CMS GC? • Un-tuned CMS results far worse Copyright © 2014 AppDynamics. All rights reserved. 34
  • 35.
  • 36.

Editor's Notes

  • #3 SLIDE3: Why AppDynamics? establish credibility through 3rd party validation Commitment to customer success Business and customer growth Describe our GTM model – ease of deployment, Enterprise grade, proven in the most demanding environments and high impact, fast   . 
  • #4 Quiz: what is the default Java stack size?
  • #5 Quiz: what is the default Java stack size? Point of slide: If you’ve ever had to manage stack size, don’t expect Java 8 behavior to be the same as Java 7 Note that you can’t directly get the stack trace depth, only the size.
  • #6 Any questions on stack memory?
  • #7 Question: how many modern apps have this object death rate? Question: what common technique completely changes this picture?
  • #8 Question: how many modern apps have this object death rate?
  • #9 Blast from the past – Java 6 HotSpot Summary: heap is basically the same in Java 6/7/8, but GC options change Any questions about heap?
  • #11 Ask if anybody is surprised by this, can explain this
  • #12 Mention performance impact if interned strings were a big source of PermGen use in Java 6 Ask about the logo
  • #13 Push on the “no max size” theme. What would happen if a program that leaked class metadata permgen in Java 6 were put onto Java 8? Can get old behavior with MaxMetaSpaceSize
  • #15 Story about how PermGen can affect monitoring tools Retransform -> app holds onto class/meta references (reflection object caching)
  • #16 A PermGen problem will be less frequent but more severe if it moves to being a metaspace problem
  • #17 Ask for any questions on memory before we switch to garbage collection
  • #19 Why 15-minute periods? – practical: time needed to tune program for proper rate of allocation plus doing all the runs for comparison.
  • #20 Tune the program:
  • #26 What are the group’s experiences? Any questions on Java 7 results, before we move onto Java 8?
  • #28 What do you think CMS looks like on Java 8 with no tuning options?
  • #36 Monitoring memory and JVM stats is only a tiny part of what AppD does