KEMBAR78
How to write memory efficient code? | PPTX
How to memory efficient Code?
Ram Lakshmanan
Architect – GCeasy.io, fastThread.io, HeapHero.io
Confoo 2019
Do I need to care about memory?
It’s very cheap!
1970s
1 Byte = 1 $
2019
FRACTION OF COST
Here is my case: Memory is not cheap!
Memory saturates first.
Other resources are
partially/under utilized.
3. Storage
4. Network
1. CPU
2. Memory
Do you know how much memory applications wastes?
30 – 90%
You can't optimize, what you can't
measure
A famous saying
How to measure wasted memory?
Step 1: Capture Heap dumps in production*
https://blog.heaphero.io/2017/10/13/how-to-capture-java-heap-dumps-7-options/
Step 2: Analyze with HeapHero: https://heaphero.io
Reports amount of memory wasted, code triggering it, recommendations to fix.
* - if possible
Analyze real-world example
String Duplication
What is duplicate String?
String s1 = new String("Hello World");
String s2 = new String("Hello World");
System.out.println(s1.equals(s2)); // prints 'true'
System.out.println((s1 == s2)); // prints 'false'
Solution 1: intern()
String s1 = new String("Hello World").intern();
String s2 = new String("Hello World").intern();
System.out.println(s1.equals(s2)); // prints 'true'
System.out.println((s1 == s2)); // prints 'true'
>>> s1 = intern(’Hello World')
Java
Python
How intern() works?
“Hello World”
s1
s2
String pool
String s1 = new String("Hello World").intern();
String s2 = new String("Hello World").intern();
Solution 2: UseStringDeduplication
• -XX:+UseStringDeduplication
• Works only with
• G1 GC algorithm
• Java 8 update 20
• Real life case study:
https://blog.gceasy.io/2018/07/17/disappointing-story-on-memory-
optimization/
Long lived objects (-XX:StringDeduplicationAgeThreshold=3)
• Check GC pause time impact
Solution 3: Use String literals
public static final String HELLO_WORLD = “Hello World”;
Solution 4: Avoid creating strings
In DB store data as primitive types:
user
id
Name …. country
1 Joe Libson …. Canada
2 Nathan Ray …. Canada
3 Chris Mang …. USA
4 Erik Pilz …. USA
5 Lakshmi
Singh
…. India
user
id
Name …. country
1 Joe Libson …. 2
2 Nathan Ray …. 2
3 Chris Mang …. 1
4 Erik Pilz …. 1
5 Lakshmi
Singh
…. 124
Inefficiency in collections
Inefficiency in Collections
List<User> users = new ArrayList<>();
users.add(user);
2 54 6 7 8 1093
wasted
11
ArrayList underlyingly maintains
Object[]
initial capacity = 10
1 2 54 6 7 8 1093
Inefficiency in Collections
wasted
List<User> users = new ArrayList<>();
for (int counter = 1; counter <= 11; ++counter) {
users.add(user);
}
1 2 54 6 7 8 1093 11 12 1514 17 18 201913 16
1 2 54 6 7 8 93 11 12 1514 17 18 201913 16 21 22 2524 26 27 28 2923 31 32 3534 37 38 403933 3630
wasted
10
for (int counter = 1; counter <= 21; ++counter) {
users.add(user);
}
Recommendation 1: use capacity
new ArrayList<>(3);
new ArrayList<>();
Recommendation 2: lazy initialization
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
private List<User> users;
public void addUser(User user) {
if (users == null) {
users = new ArrayList<>();
}
users.add(user);
}
Recommendation 3: avoid clear()
List<User> users = new ArrayList<>();
users = null;
List<User> users = new ArrayList<>();
users.clear();
Let’s understand overhead of an
Object
Object overhead
public class User {
private String name;
private int age;
private float weight;
}
new User();
Object Header
name
age
weight
12 bytes
4 bytes
4 bytes
4 bytes
Fixed overhead
1. Virtual method invocation
2. ‘synchronized’ object lock
3. Garbage collection
4. Object book keeping
24 bytes
Boxed numbers: java.lang.Integer
• int: 4 bytes
• java.lang.Integer: 16 bytes
Data is 4 bytes, object overhead is 12 bytes
Yesterday’s key note: 2 instance variables/class
public class User {
private int field1;
private int field2;
private int field3;
:
private int field10;
}
public class User {
private Object1 obj1;
private Object2 obj2;
}
public class Object1 {
private int field1;
private Object3 obj3;
}
public class Object2 {
private int field2;
private Object4 obj4;
}
public class Object3 {
private int field3;
private Object5 obj5;
}
public class Object4 {
private int field4;
private Object6 obj6;
}52 bytes
i.e. 12 bytes header + (10 ints* 4 bytes) public class Object5 {
private int field5;
private Object6 obj7;
}
public class Object6 {
private int field6;
private Object3 obj8;
}
public class Object7 {
private int field7;
private Object4 obj9;
}
public class Object8 {
private int field8;
private int field9;
}
public class Object9 {
private int field10;
}
196 bytes (~4x more needed)
= 10 object headers * 12 + (10 ints * 4 bytes)
+ (9 object references * 4)
How all memory is wasted?
1. Duplicate Strings: https://heaphero.io/heap-recommendations/duplicate-strings.html
2. Wrong memory size settings
3. Inefficient Collections: http://heaphero.io/heap-recommendations/inefficient-collections.html
4. Duplicate Objects: https://heaphero.io/heap-recommendations/duplicate-objects.html
5. Duplicate arrays: https://heaphero.io/heap-recommendations/duplicate-primitive-arrays.html
6. Inefficient arrays: https://heaphero.io/heap-recommendations/inefficient-primitive-arrays.html
7. Objects waiting for finalization: https://heaphero.io/heap-recommendations/objects-waiting-
finalization.html
8. Boxed numbers: https://heaphero.io/heap-recommendations/boxed-numbers.html
9. Object Headers: https://heaphero.io/heap-recommendations/object-headers.html
Reduce computing cost
Better Response time
Reduce Garbage Collection Pause Time
Optimizing memory
Fascinating to read
Thank you!!
ram@tier1app.com
Ram Lakshmanan
@tier1app
https://www.linkedin.com/company/gceasy
Any Questions
Deck will be published in:
http://blog.heaphero.io

How to write memory efficient code?

  • 1.
    How to memoryefficient Code? Ram Lakshmanan Architect – GCeasy.io, fastThread.io, HeapHero.io Confoo 2019
  • 2.
    Do I needto care about memory? It’s very cheap! 1970s 1 Byte = 1 $ 2019 FRACTION OF COST
  • 3.
    Here is mycase: Memory is not cheap! Memory saturates first. Other resources are partially/under utilized. 3. Storage 4. Network 1. CPU 2. Memory
  • 4.
    Do you knowhow much memory applications wastes? 30 – 90%
  • 5.
    You can't optimize,what you can't measure A famous saying
  • 6.
    How to measurewasted memory? Step 1: Capture Heap dumps in production* https://blog.heaphero.io/2017/10/13/how-to-capture-java-heap-dumps-7-options/ Step 2: Analyze with HeapHero: https://heaphero.io Reports amount of memory wasted, code triggering it, recommendations to fix. * - if possible
  • 7.
  • 8.
  • 9.
    What is duplicateString? String s1 = new String("Hello World"); String s2 = new String("Hello World"); System.out.println(s1.equals(s2)); // prints 'true' System.out.println((s1 == s2)); // prints 'false'
  • 10.
    Solution 1: intern() Strings1 = new String("Hello World").intern(); String s2 = new String("Hello World").intern(); System.out.println(s1.equals(s2)); // prints 'true' System.out.println((s1 == s2)); // prints 'true' >>> s1 = intern(’Hello World') Java Python
  • 11.
    How intern() works? “HelloWorld” s1 s2 String pool String s1 = new String("Hello World").intern(); String s2 = new String("Hello World").intern();
  • 12.
    Solution 2: UseStringDeduplication •-XX:+UseStringDeduplication • Works only with • G1 GC algorithm • Java 8 update 20 • Real life case study: https://blog.gceasy.io/2018/07/17/disappointing-story-on-memory- optimization/ Long lived objects (-XX:StringDeduplicationAgeThreshold=3) • Check GC pause time impact
  • 13.
    Solution 3: UseString literals public static final String HELLO_WORLD = “Hello World”;
  • 14.
    Solution 4: Avoidcreating strings In DB store data as primitive types: user id Name …. country 1 Joe Libson …. Canada 2 Nathan Ray …. Canada 3 Chris Mang …. USA 4 Erik Pilz …. USA 5 Lakshmi Singh …. India user id Name …. country 1 Joe Libson …. 2 2 Nathan Ray …. 2 3 Chris Mang …. 1 4 Erik Pilz …. 1 5 Lakshmi Singh …. 124
  • 15.
  • 16.
    Inefficiency in Collections List<User>users = new ArrayList<>(); users.add(user); 2 54 6 7 8 1093 wasted 11 ArrayList underlyingly maintains Object[] initial capacity = 10
  • 17.
    1 2 546 7 8 1093 Inefficiency in Collections wasted List<User> users = new ArrayList<>(); for (int counter = 1; counter <= 11; ++counter) { users.add(user); } 1 2 54 6 7 8 1093 11 12 1514 17 18 201913 16 1 2 54 6 7 8 93 11 12 1514 17 18 201913 16 21 22 2524 26 27 28 2923 31 32 3534 37 38 403933 3630 wasted 10 for (int counter = 1; counter <= 21; ++counter) { users.add(user); }
  • 18.
    Recommendation 1: usecapacity new ArrayList<>(3); new ArrayList<>();
  • 19.
    Recommendation 2: lazyinitialization private List<User> users = new ArrayList<>(); public void addUser(User user) { users.add(user); } private List<User> users; public void addUser(User user) { if (users == null) { users = new ArrayList<>(); } users.add(user); }
  • 20.
    Recommendation 3: avoidclear() List<User> users = new ArrayList<>(); users = null; List<User> users = new ArrayList<>(); users.clear();
  • 21.
  • 22.
    Object overhead public classUser { private String name; private int age; private float weight; } new User(); Object Header name age weight 12 bytes 4 bytes 4 bytes 4 bytes Fixed overhead 1. Virtual method invocation 2. ‘synchronized’ object lock 3. Garbage collection 4. Object book keeping 24 bytes
  • 23.
    Boxed numbers: java.lang.Integer •int: 4 bytes • java.lang.Integer: 16 bytes Data is 4 bytes, object overhead is 12 bytes
  • 24.
    Yesterday’s key note:2 instance variables/class public class User { private int field1; private int field2; private int field3; : private int field10; } public class User { private Object1 obj1; private Object2 obj2; } public class Object1 { private int field1; private Object3 obj3; } public class Object2 { private int field2; private Object4 obj4; } public class Object3 { private int field3; private Object5 obj5; } public class Object4 { private int field4; private Object6 obj6; }52 bytes i.e. 12 bytes header + (10 ints* 4 bytes) public class Object5 { private int field5; private Object6 obj7; } public class Object6 { private int field6; private Object3 obj8; } public class Object7 { private int field7; private Object4 obj9; } public class Object8 { private int field8; private int field9; } public class Object9 { private int field10; } 196 bytes (~4x more needed) = 10 object headers * 12 + (10 ints * 4 bytes) + (9 object references * 4)
  • 25.
    How all memoryis wasted? 1. Duplicate Strings: https://heaphero.io/heap-recommendations/duplicate-strings.html 2. Wrong memory size settings 3. Inefficient Collections: http://heaphero.io/heap-recommendations/inefficient-collections.html 4. Duplicate Objects: https://heaphero.io/heap-recommendations/duplicate-objects.html 5. Duplicate arrays: https://heaphero.io/heap-recommendations/duplicate-primitive-arrays.html 6. Inefficient arrays: https://heaphero.io/heap-recommendations/inefficient-primitive-arrays.html 7. Objects waiting for finalization: https://heaphero.io/heap-recommendations/objects-waiting- finalization.html 8. Boxed numbers: https://heaphero.io/heap-recommendations/boxed-numbers.html 9. Object Headers: https://heaphero.io/heap-recommendations/object-headers.html
  • 26.
    Reduce computing cost BetterResponse time Reduce Garbage Collection Pause Time Optimizing memory
  • 27.
  • 28.

Editor's Notes

  • #8 https://heaphero.io/my-heap-report.jsp?p=YXJjaGl2ZWQvMjAxOS8wMy8xNC8tLVRQQkUxLWhlYXBkdW1wLTE3XzA4XzE3XzEwXzMwLmJpbi5nei0zLTQ0LTE1Lmpzb24tLQ== https://heaphero.io/my-heap-report.jsp?p=YXJjaGl2ZWQvMjAxOS8wMy8xNC8tLVRQU1AxLWhlYXBkdW1wLTE3XzA4XzE3XzEwXzMwLmJpbi5nei0zLTI1LTI3Lmpzb24tLQ==