24 2007 1 Java A Method to Reduce the Memory Footprint of Java VM Kiyokuni KAWACHIYA Kazunori OGATA Tamiya ONODERA IBM Research, Tokyo Research Laboratory kawatiya@jp.ibm.com Java Java 30% String char 2 GC StringGC IBM Java StringGC 90% 15% 1 String 2 Java [7] C Java StringGC char Java IBM Java 90% Java [5, 15] 15% Java Java Java char char[] StringGC 30% char StringGC String 2 Java String A. String 3 B. char StringGC 17% 4 StringGC 5 6
24 2007 2 1 public final class String... { // private 2 private char[] value; // char 3 private int offset; // char 4 private int count; // 5 : 6 } <head> String object <body> char[ ] object [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] (header) (header) s t r i n g value offset count 1: String 2 Java StringBuffer.toString() String.substring() Java String char 2 2.1 Java 2 Java Java String 9 String jar2 [7] 2 34 char 26 String immutable char 4 StringBuffer StringBuffer char javac Java String Java Java 1 String char Apache Harmony 2 [1] jar2 usrjar "user.jar" Java 2 String String 3 char value offset count value Java char String char String offset count 2 int 1 1 header Java 1 String "string" 1 2 StringBuffer insert(), delete() String private char StringBuffer char StringBuffer
24 2007 3 (header) value offset count 1 class StringSample { 2 public static void main(string[] args) { 3 String sysjar = "system.jar", usrjar = "user.jar"; 4 String tmpstr = sysjar + ":" + usrjar + ":" + "."; 5 int colon1 = tmpstr.indexof(":"), 6 int colon2 = tmpstr.indexof(":", colon1+1); 7 String jar2 = tmpstr.substring(colon1+1, colon2); 8 tmpstr = null; 9 10 System.out.println(jar2); // "user.jar" 11 } 12 } String jar2 (="user.jar") char[ ] object (length=34) (header) s y s t e m. j a r : u s e r. j a r :. \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] unused area unused area 2: Java Trade6: IBM WebSphere Application Server (WAS) GC [11] [10] Version 6.1 Trade6 2 [9] String char 3 GC Tuscany: Service Component Architecture (SCA) [13] Java 2.2 SCA BigBank Java XML 3 1 2 GC Java J9 Java VM type-accurate GC [11] [4] IBM Java J9 VM [4, 8] 1.5.0 for Linux String GC value char Java Tuscany [3] Incubating-M1 Apache Tomcat [2] String
24 2007 4 Trade6 Tuscany 621,463 33,938 KB 281,973 15,332 KB String 106,957 2,995 KB 57,922 1,622 KB - 42,163 1,181 KB 33,939 950 KB char 97,306 9,641 KB 49,150 4,470 KB - String 95,639 8,810 KB 48,118 3,628 KB - 32,839 2,107 KB 25,578 1,596 KB - 5,923 139 KB 2,019 46 KB 75,002 3,427 KB 59,517 2,593 KB - 12.1% 10.1% 21.1% 16.9% 1: Java 3 Trade6 106,957 String 42,163 39.4% 30 50% char 10 17% String Java String StringBuffer char 98% char String 3 StringGC String String 2 char Java 17% char A. String 2 char B. char 35% Java 4 StringGC 3.1 StringGC Java Java String 5 12MB stop-theworld GC 3 String 100 99 [11] StringGC 4 char 3.2
24 2007 5 1: String char A String char String C char String String E GC String F 2: String String (a) StringGC String String B, C GC A String String D 3.3 String E 3: String char F char String (b) StringGC 3: StringGC char String A F char value offset 4 B 4: String char 3.2 String B String D String A char StringGC GC char char 1 String char char String StringGC n 3 StringGC (a) char B String A 1 (b) "java" String GC B C 2 char String GC String char 3 String
24 2007 6 1 class BadManner { 2 public static void main(string[] args) { 2 4 3 String s1 = new String("java"); 4 String s2 = new String("java"); 3 char 5 if (s1 == s2) // should use s1.equals(s2) 6 System.out.println("Same Strings"); String 7 else 8 System.out.println("Different Strings"); 9 } 10 } 3(a) 3 char 4: String char String.substring() Java == 4 char System.identityHashCode() 4 char String s1 s2 char Different Strings 4 3 Same Strings Java == 4 1 char String.equals() char Java String 3 "java" char String char 2 char 3 String char "String" 1 65% 1 String String char String.equals() 30 50% 2 GC == String StringGC String 3.3 value offset Java StringGC 2 String StringGC String 3 Java final "java" String B String C String
24 2007 7 String String GC String 5 StringGC Nursery 1 GC String String A1 A0 B1 GC [11] C1 String tenuring Nursery 2 2.2 Java VM tenure Tenured space String C0 Tenured- String String table GC StringGC offset String char 3.4 3.1 StringGC (a) GC 2 Tenured space 1 String C0 Tenured- String table Java String 10 String A1 StringGC 1 90% Nursery 1 Nursery 2 String (b) GC String 5: StringGC String String 4 GC String 3.4 Java StringGC String 2 3.06 GHz String A0 String C1 String A0,A1 Unified String B1 Nursery 1 String B1 Tenured Copied String C1 Nursery 2
24 2007 8 1 class MicroBench { 2 static String[] docreate(int dupratio) { 3 String[] strs = new String[1000000]; 4 int n = 0, dupcount = 1000000 * dupratio/100; 5 for (int i = 0; i < dupcount; i++) 6 strs[i] = "STR_"+n; //"STR_0" 7 for (int i = dupcount; i < 1000000; i++) Number of live objects [M objects] 3 Original JVM 2 With StringGC 8 strs[i] = "STR_"+(++n);//"STR_1","STR_2",... 9 return strs; 1 10 } 11 static int docompare(string[] strs) { 12 String str0 = "STR_0"; 0 13 int dupcount = 0; 0 10 20 30 40 50 60 70 80 90 100 14 for (int i = 0; i < 1000000; i++) dupratio [%] 15 if (strs[i].equals(str0)) dupcount++; Live heap size [MBytes] 16 return dupcount*100 / 1000000;//==dupRatio 100 17 } Original JVM With StringGC 18 : 19 } 6: StringGC 50 Xeon 4 GB Red Hat Enterprise Linux 3 AS PC 4.1 0 0 10 20 30 40 50 60 70 80 90 100 dupratio [%] 7: docreate() StringGC 6 StringGC docreate() dupratio StringBuffer 100 StringGC dupratio String dupratio "STR 0" String 100 String dupratio StringGC / Java VM dupratio docreate() 3.3 7 String String StringGC dupratio StringGC 6 docompare() dupratio docreate() 100 String String.equals() "STR 0" dupratio String dupratio StringGC String 8 dupratio 70% StringGC dupratio String String 8 docreate() StringGC
24 2007 9 Relative time for docreate() (smaller is better) 4 Original JVM 3 2 1 With StringGC 0 0 10 20 30 40 50 60 70 80 90 100 dupratio [%] Relative time for docompare() (smaller is better) 4 Original JVM With StringGC 9: SPECjvm98 3 2 1 0 0 10 20 30 40 50 60 70 80 90 100 dupratio [%] Java 8: docreate() docompare() 2.2 Trade6 Tuscany String 2 Trade6 dupratio StringGC String 38.7% docreate() char 32.0% docompare() JIT 9.2% Tuscany String 52.9% char 4.2 5 String String.equals() 146 227 mtrt 3.6% StringGC StringGC 46.3% 15.0% 1 StringGC Java StringGC SPECjvm98 90% [14] 5 5 3 StringGC 9 StringGC 1 StringGC Java StringGC String.intern() 209 db 30% 8 String String Java VM String String 1 8 String
24 2007 10 Java VM Trade6 Tuscany 621,463 33,938 KB 281,973 15,332 KB - String 106,957 2,995 KB 57,922 1,622 KB - char 97,306 9,641 KB 49,150 4,470 KB StringGC 547,999 30,824 KB 228,379 13,026 KB - String 65,584 1,836 KB 27,306 765 KB - char 66,149 7,662 KB 26,370 3,032 KB 72,530 3,137 KB 53,396 2,295 KB - 11.7% 9.2% 18.9% 15.0% - 89.6% 91.5% 86.8% 88.5% 2: StringGC Java String [6] Marinov O Callahan Java Java Object Equality String Profiling OEP [12] OEP == Java String String String 6 Java 3.4 StringGC String StringGC Java XML Java String StringGC [7] C xstr(1) GC String IBM Java J9 VM Java StringGC 1 90% Java 15% Dieckmann Hölzle StringGC SPECjvm98 3.2
24 2007 11 StringGC Java [13] Open SOA. Service Component Architecture Home. http://osoa.org/display/main/service+ Component+Architecture+Home [14] Standard Performance Evaluation Corporation. SPEC JVM98 Benchmarks. http://www.spec.org/osg/jvm98/ IBM [15] Sun Microsystems. Class Data Sharing, 2004. http://java.sun.com/j2se/1.5.0/docs/guide/ vm/class-data-sharing.html [1] The Apache Software Foundation. Apache Harmony. http://harmony.apache.org/ [2] The Apache Software Foundation. Apache Tomcat. http://tomcat.apache.org/ [3] The Apache Software Foundation. Apache Tuscany. http://incubator.apache.org/tuscany/ [4] C. Bailey. Java Technology, IBM Style: Introduction to the IBM Developer Kit: An overview of the new functions and features in the IBM implementation of Java 5.0, 2006. http://www.ibm.com/developerworks/java/ library/j-ibmjava1.html [5] B. Corrie. Java Technology, IBM Style: Class Sharing: The Shared Classes feature helps reduces memory footprint and improves startup performance, 2006. http://www.ibm.com/developerworks/java/ library/j-ibmjava4/ [6] S. Dieckmann and U. Hölzle. A Study of the Allocation Behavior of the SPECjvm98 Java Benchmark. Proc. ECOOP 99, 92 115, 1999. [7] J. Gosling, B. Joy, G. Steele, and G. Bracha. The Java Language Specification, Third Edition, Addison Wesley, 2005. [8] N. Grcevski, A. Kielstra, K. Stoodley, M. Stoodley, and V. Sundaresan. Java Just-In-Time Compiler and Virtual Machine Improvements for Server and Middleware Applications. Proc. USENIX VM 04, 151 162, 2004. [9] IBM Corporation. IBM Trade Performance Benchmark. https://www14.software.ibm.com/webapp/iwm/ web/prelogin.do?source=trade6 [10] IBM Corporation. WebSphere Application Server: Product Overview. http://www.ibm.com/software/webservers/ appserv/was/ [11] R. Jones and R. Lins. Garbage Collection: Algorithms for Automatic Dynamic Memory Management, Wiley, 1996. [12] D. Marinov and R. O Callahan. Object Equality Profiling. Proc. OOPSLA 03, 313 325, 2003.