1. Mark-and-Sweep Garbage Collection
Transcription
1. Mark-and-Sweep Garbage Collection
CS3214 Spring 2015 Exercise 4 Due: Tuesday, April 21, 2015. 11:59pm (no extensions). What to submit: A tar ball containing the files: Slide.java, slide.png or slide.pdf with your slide, benchmark.template, and any file(s) containing the source code for your solution to part 1. The theme of this exercise is automatic memory management. Parts 2 and 3 of this exercise must be done on the rlogin cluster machines. 1. Mark-and-Sweep Garbage Collection The first part of the exercise involves a recreational programming exercise that is intended to deepen your understanding of how a garbage collector works. You are asked to implement a simple mark-and-sweep collector using a synthetic heap dump given as input. On the heap, there are n objects numbered 0 . . . n − 1 with sizes s0 . . . sn−1 . Also given are r roots and m pointers, i.e., references stored in objects that refer to other objects. Write a program that performs a mark-and-sweep collection and outputs the total size of the live heap as well as the total amount of memory a mark-and-sweep collector would sweep if this heap were garbage collected. We will do this problem programming competition style. Write a program - in any language you choose1 - that reads a heap description and outputs the size of the live heap and the amount of garbage swept. Your program should read from standard input. Each invocation of your program should process a single test case. The first line contains three non-negative 32-bit integers n, m, r such that r ≤ n. The second line contains n positive 32-bit integers si that denote the size si of object i. Following that are m lines with tuples i, j for which 0 ≤ i, j < n, each of which denotes a pair of object indices. A tuple (i, j) means that object i stores a reference to object j, keeping it alive (provided si is reachable from a root). The description of the references is followed by a single line with r integers denoting the roots of the reachability graph R0 . . . Rr−1 . Your program should output to standard out two numbers l s on a single line, where l represents the total size of the live heap and s represents the amount of garbage that would be swept if the heap were collected. Sample Input: 1 and which is available on the rlogin cluster so we can grade your submission. [email protected] if you need a language not currently installed. 1 Contact tech- CS3214 Spring 2015 Exercise 4 Figure 1: The heap graph given in the sample input. Roots are shown using double circles. The numbers in parentheses are the sizes of individual nodes. Here, root 4 keeps alive object 7, which keeps 1 alive, which in turn keeps 5 and 6 alive. Root 8 keeps object 10 alive. 12 11 2 5 17 5 40 37 30 14 39 22 21 15 21 4 7 2 0 7 1 11 5 8 10 1 5 1 6 0 10 5 7 9 5 11 6 8 4 Sample Output: 174 92 Figure 1 shows the reachability graph for the sample input/output. We will test your program on additional inputs. 2 CS3214 Spring 2015 Exercise 4 2. Drawing a Slide In type-safe languages such as Java or C # , many sources of memory-related errors have been eliminated. Memory leaks remain as a serious source of error you will encounter in your practice as a programmer. Memory leaks increase garbage collection frequency because they reduce the amount of free heap space, and they make every full garbage collection more expensive since leaked objects will typically be tenured in the oldest generation. Eventually, they lead to an out-of-memory error if the size of the uncollectable live heap exceeds the virtual machine’s maximum heap size. To understand how memory leaks form, it is crucial to have an understanding of how a program’s operations affect the size of the live heap. To illustrate this, I have a created a heap tracking JVMTI agent which allows a program to determine the size of the live heap and write this information to a log file while the program runs. An example is shown in Figure 2, which results from the provided sample program TrackerSample.java, shown below: /* * Example of how to use the Java live heap tracker * * @author [email protected] for CS 3214 Fall 2014 */ public class TrackerSample { public static void main(String []av) throws Exception { int [][] a = new int[4][]; HeapTracker.startTrace(); // start tracing HeapTracker.takeLiveHeapSample(); // take sample a[0] = new int[50000]; HeapTracker.takeLiveHeapSample(); // take sample Thread.sleep(100); a[1] = new int[20000]; HeapTracker.takeLiveHeapSample(); // take sample Thread.sleep(100); a[2] = new int[10000]; HeapTracker.takeLiveHeapSample(); // take sample Thread.sleep(100); a[3] = new int[5000]; HeapTracker.takeLiveHeapSample(); // take sample HeapTracker.stopTrace(); // stop tracing } } Your task in this part of the exercise is simple: write a Java program that, when run under my heap tracker program, will produce a live heap profile that resembles a playground slide like the one shown in 3. To run the heap tracker compile and run it like so: 3 CS3214 Spring 2015 Exercise 4 600000 live memory for tracker sample 550000 500000 450000 400000 350000 300000 250000 200000 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 Figure 2: The live memory graph of the provided TrackerSample.java program. Note that the live memory does not start at 0 when tracking starts since there is live memory already in use by the JVM’s runtime library. javac -cp /home/courses/cs3214/bin/heaptracker/heapTracker.jar:. TrackerSample.java runtracker TrackerSample This should produce a file heaptrace.dat in the current directory. Use a plotting program such as gnuplot or similar to produce a chart that shows the live heap profile. 3. Garbage Collection and Performance Garbage collectors are continuously improved. No single garbage collection algorithm is suitable for every situation: workload characteristics such as the allocation rate, the distribution of the lifetimes of allocated objects, and the live heap profile influence the performance of a garbage collector for a given workload. In addition to the garbage collection algorithm, the performance of a program also depends on the amount of memory the virtual machine is allowed to occupy (that is, the maximum heap size to which it can grow), as well as the amount of CPU resources a JVM may use. For this part of the exercise, we are asking that you simply run a program under different collectors and find out where it runs the fastest. Use an unloaded rlogin machine (use uptime(1)) to perform these experiments. See the JDK 8 documentation for a full list of 4 CS3214 Spring 2015 Exercise 4 450000 live memory for slide 400000 350000 300000 250000 200000 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Figure 3: Write a program that produces this live memory profile that resembles a slide. The x/y dimensions do not need to match exactly. GC-related flags. We have provided some Java code in a file tightknight.jar and input data in tightknight1a.in, which contain a sample solution to one of the problems in this year’s ACM ICPC regional programming contest.2 Run this code like so: time java -cp tightknight.jar maxflow.TightKnight < tightknight1a.in it should produce output similar to: No graph building 7.25s maxflow solver 1.17s real user sys 0m8.546s 1m18.133s 0m6.502s Write down the numbers listed in the “real” and “user” rubrics, representing elapsed wall-clock time and CPU time, respectively. For instance, in the example above, the program ran for 8.546s, but took up 1m18.133s of CPU time. 2 If you like to know what this problem does and why it’s called “Tight Knight” then ask Scott who solved this problem for our team. 5 CS3214 Spring 2015 Exercise 4 Tabulate wall-clock time and CPU time for the following combinations: | real | user -------------------------------------+--------------+---------------Default | 8.546s | 1m18.133s With 1 core, taskset -c 8 java ... | | With 4GB initial heap, -Xms4g | | With 8GB initial heap, -Xms8g | | With 16GB initial heap, -Xms16g | | With -XX:+UseConcMarkSweepGC | | With -XX:+UseParallelGC | | With -XX:+UseParallelOldGC | | With -XX:+UseSerialGC | | With -XX:+UseG1GC | | | | Extra Credit: Best combination you can find | | from the JDK documentation: | | | | __________________________ | | Read the man page for taskset to understand how to use this command. For the “best combination,” try to tune the collector to achieve better performance than the combinations already listed in the table, with the additional constraint that the initial heap size remain the default. 6