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.
staff@cs.vt.edu 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 godmar@gmail.com 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