To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 1254fa4e authored by john's avatar john
Browse files

added some memory analysis tools

parent a77dc9b8
#
# Copyright (c) 2009 The Australian National University.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License v2.0.
# You may obtain the license at
#
# http://www.opensource.org/licenses/apache2.0.php
#
# Source lists
LIBNAME=dacapoagent
SOURCES=dacapooptions.c dacapoagent.c dacapoexception.c dacapolog.c dacapotag.c dacapolock.c dacapomonitor.c dacapothread.c \
dacapoallocation.c dacapomethod.c dacapocallchain.c
# Linux GNU C Compiler
ifeq ($(OSNAME), linux)
# GNU Compiler options needed to build it
COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer -D_LARGEFILE64_SOURCE=1
# Options that help find errors
COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses -pthread
# ifeq ($(OPT), true)
CFLAGS=-O2 $(COMMON_FLAGS)
# else
# CFLAGS=-g $(COMMON_FLAGS)
# endif
# Object files needed to create library
OBJECTS=$(SOURCES:%.c=%.o)
# Library name and options needed to build it
LIBRARY=lib$(LIBNAME).so
LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc -mimpure-text
# Libraries we are dependent on
LIBRARIES=-L $(JAVA_HOME)/jre/lib/$(LIBARCH) -lc
# LIBRARIES+= -L $(ZLIB_DIR) -l $(ZLIB_LIB)
OBJECTS+= $(ZLIB_DIR)/lib$(ZLIB_LIB).a
# Building a shared library
LINK_SHARED=$(LINK.c) -shared -o $@
endif
# Common -I options
CFLAGS += -I. -I$(ZLIB_DIR)
CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(OSNAME)
# Default rule (build both native library and jar file)
all: $(LIBRARY)
# Build native library
$(LIBRARY): $(OBJECTS)
$(LINK_SHARED) $(OBJECTS) $(LIBRARIES)
# Cleanup the built bits
clean:
rm -f -r classes
rm -f $(LIBRARY) $(OBJECTS)
# Simple tester
test: all
LD_LIBRARY_PATH=. $(JAVA_HOME)/bin/java -agentlib:$(LIBNAME) -Xbootclasspath/a:./$(JARFILE) -version
......@@ -64,7 +64,8 @@ public class Instrument extends ClassAdapter {
options = new Options(commandLineOptions);
cv = new SystemInstrument(cv, methodToLargestLocal);
// Unable to
// cv = new SystemInstrument(cv, methodToLargestLocal);
if (options.has(Options.RUNTIME))
cv = new RuntimeInstrument(cv, methodToLargestLocal);
......
......@@ -37,8 +37,6 @@ public class SystemInstrument extends Instrument {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
String systemClassName = System.class.getName().replace('.','/');
System.err.println("Class: "+name+" extends: "+superName);
if (systemClassName.equals(name)) {
doneAddField = false;
doneAddMethod = false;
......
package org.dacapo.analysis.memory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
public class CommandLineArgs {
public static final String DEFAULT_CLASSPATH = "store";
public static final String DEFAULT_LOG_FILE = "log_file";
public static final String OPT_ALL = "all";
public static final String OPT_CLASSPATH = "classpath";
public static final String OPT_LOG_FILE = "logfile";
public static final String OPT_HELP = "help";
public static final String OPT_LOGGED_CLASSES = "loggedclasses";
public static final String OPT_INDIVIDUAL = "individual";
public static final String OPT_OUTPUT_FILE = "output";
public static final String STDOUT_NAME = "-";
public static final int EXIT_BAD_COMMANDLINE = 1;
private static final Option[] OPTIONS = {
makeOption("a", OPT_ALL, "all allocations and deallocations", null),
makeOption("c", OPT_CLASSPATH, "classpath to read the java files from", "classpath"),
makeOption("f", OPT_LOG_FILE, "specify the log file", "log_file"),
makeOption("l", OPT_LOGGED_CLASSES, "only analyse classes loaded during log phase", null),
makeOption("i", OPT_INDIVIDUAL, "report metrics for individual classes", null),
makeOption("o", OPT_OUTPUT_FILE, "output CSV file for metrics", "output"),
makeOption("h", OPT_HELP, "help", null)
};
private static CommandLineParser parser = new PosixParser();
private static Options options = new Options();
private static Options visibleOptions = new Options();
private static OutputStream os = null;
{
// Construct the option list and the visibleOption list.
// The option list is used for parsing the command line,
// where as the visibleOption is a subset of the option list
// and is used for producing the usage help.
for (int i = 0; i < OPTIONS.length; i++) {
options.addOption(OPTIONS[i]);
if (OPTIONS[i].getDescription() != null)
visibleOptions.addOption(OPTIONS[i]);
}
}
private CommandLine line;
private LinkedList<String> classpath = null;
CommandLineArgs(String[] args) throws Exception {
try {
boolean reportAndExitOk = false;
line = parser.parse(options, args);
} catch (ParseException e) {
System.err.println("Command line exception: " + e.getMessage());
System.exit(EXIT_BAD_COMMANDLINE);
} catch (Exception e) {
System.err.println("Exception processing command line values: "
+ e.getMessage());
System.exit(EXIT_BAD_COMMANDLINE);
}
}
LinkedList<String> getClassPath() {
if (classpath!=null)
return classpath;
String cp = line.getOptionValue(OPT_CLASSPATH,DEFAULT_CLASSPATH);
classpath = new LinkedList<String>();
for(String c: cp.split(":")) {
classpath.add(c);
}
return classpath;
}
String getLogFile() {
return line.getOptionValue(OPT_LOG_FILE,DEFAULT_LOG_FILE);
}
boolean getAll() {
return line.hasOption(OPT_ALL);
}
boolean getLogged() {
return line.hasOption(OPT_LOGGED_CLASSES);
}
boolean getIndividual() {
return line.hasOption(OPT_INDIVIDUAL);
}
OutputStream getOutputStream() throws FileNotFoundException {
if (os != null)
return os;
String fileName = line.getOptionValue(OPT_OUTPUT_FILE,STDOUT_NAME);
if (fileName.equals(STDOUT_NAME)) {
os = System.out;
} else {
if (fileName.startsWith("-")) fileName = fileName.substring(1);
os = new FileOutputStream(new File(fileName));
}
return os;
}
/*
* Define a commandline option.
*
* @param shortName An optional short form name for the command line option.
*
* @param longname A commandline option must have a long form name.
*
* @param description All commandline options that are visible options must
* have a description, commandline options that are for internal development
* usage must not have a description and must instead be documented in the
* code.
*
* @param argName A commandline option that requires has an argument must
* specify an argument name.
*/
private static Option makeOption(String shortName, String longName,
String description, String argName) {
assert longName != null;
Option option = new Option(shortName, longName, argName != null,
description);
if (argName != null) {
option.setValueSeparator('=');
option.setArgName(argName);
}
return option;
}
}
package org.dacapo.analysis.memory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.LinkedList;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
import gr.spinellis.ckjm.*;
import org.apache.bcel.generic.Type;
import org.dacapo.analysis.util.CSVInputStream;
import org.dacapo.analysis.util.CSVOutputStream;
import org.dacapo.analysis.util.CSVInputStream.CSVException;
import org.dacapo.analysis.util.events.Event;
import org.dacapo.analysis.util.events.EventAllocation;
import org.dacapo.analysis.util.events.EventClassPrepare;
import org.dacapo.analysis.util.events.EventErrorListener;
import org.dacapo.analysis.util.events.EventFree;
import org.dacapo.analysis.util.events.EventHeapReport;
import org.dacapo.analysis.util.events.EventListener;
import org.dacapo.analysis.util.events.EventParseException;
import org.dacapo.analysis.util.events.EventPointerChange;
import org.dacapo.analysis.util.events.EventStart;
import org.dacapo.analysis.util.events.EventStop;
import org.dacapo.analysis.util.LogFiles;
import org.apache.bcel.Repository;
import org.apache.bcel.util.ClassPath;
import org.apache.bcel.util.SyntheticRepository;
import org.dacapo.instrument.LogTags;
public class Memory {
private static final String CLASS_EXTENSION = ".class";
public static void main(String[] args) throws Exception {
CommandLineArgs commandLine = new CommandLineArgs(args);
LinkedList<File> fileList = LogFiles.orderedLogFileList(commandLine.getLogFile());
AllocationListener listener = new AllocationListener(new CSVOutputStream(commandLine.getOutputStream()), commandLine.getAll());
listener.processStart();
EventErrorListener eventErrorListener = new EventErrorListener() {
public void handle(EventParseException e) throws EventParseException { System.err.println(e); }
public void handle(CSVException e) throws CSVException { System.err.println(e); }
};
for(File file: fileList) {
CSVInputStream is = new CSVInputStream(new FileInputStream(file));
Event.parseEvents(listener, is, eventErrorListener);
}
listener.processStop();
}
private final static class Allocation {
private AllocationListener allocationListener;
private Long tag;
private String className;
private long totalAllocation = 0;
private long currentAllocation = 0;
private long totalObjects = 0;
private long currentObjects = 0;
private long negativeTagCount = 0;
public Allocation(AllocationListener allocationListener, Long tag, String className) {
assert allocationListener != null;
assert tag != null;
assert className != null;
this.allocationListener = allocationListener;
this.tag = tag;
this.className = className;
}
public void allocate(Long size) {
this.totalAllocation += size;
this.currentAllocation += size;
this.totalObjects ++;
this.currentObjects ++;
this.allocationListener.allocate(size);
}
public void deallocate(Long size) {
this.currentAllocation -= size;
this.currentObjects --;
this.allocationListener.deallocate(size);
}
public void addObjectTag(Long objectTag) {
if (objectTag != null && objectTag < 0) {
negativeTagCount++;
this.allocationListener.addObjectTag(objectTag);
}
}
public long getClassTag() { return this.tag; }
public String getClassName() { return this.className; }
public void setClassName(String className) { this.className = className; }
public long getTotalAllocation() { return this.totalAllocation; }
public long getCurrentAllocation() { return this.currentAllocation; }
public static void writeHeadings(CSVOutputStream os) {
os.write("Type");
os.write("ClassName");
os.write("Total Bytes");
os.write("Current Bytes");
os.write("Negative Tag Count");
os.write("Total Objects");
os.write("Current Objects");
os.write("Pointer Mutations");
os.eol();
}
public void write(CSVOutputStream os) {
if (this.className.startsWith("["))
os.write("ARRAY");
else
os.write("OBJECT");
os.write(this.className);
os.write(""+this.totalAllocation);
os.write(""+this.currentAllocation);
os.write(""+this.negativeTagCount);
os.write(""+this.totalObjects);
os.write(""+this.currentObjects);
os.eol();
}
}
private final static class Pair {
public Allocation type;
public Long size;
public Pair(Allocation type, Long size) {
this.type = type;
this.size = size;
}
}
private final static class AllocationListener extends EventListener {
long totalAllocation = 0;
long currentAllocation = 0;
long totalObjects = 0;
long currentObjects = 0;
long negativeTagCount = 0;
long pointerMutations = 0;
TreeMap<Long,String> tagToClass = new TreeMap<Long,String>();
TreeMap<String,Long> classToTag = new TreeMap<String,Long>();
TreeMap<Long,Allocation> allocation = new TreeMap<Long,Allocation>();
TreeMap<Long,Pair> objectAlloc = new TreeMap<Long,Pair>();
CSVOutputStream os;
boolean all;
public AllocationListener(CSVOutputStream os, boolean all) {
this.os = os;
this.all = all;
}
public void processStart() { }
public void processEvent(Event e) {
if (e.getLogPrefix() == LogTags.LOG_PREFIX_CLASS_PREPARE) {
EventClassPrepare eCP = (EventClassPrepare)e;
map(eCP.getClassTag(), eCP.getClassName());
} else if (all || getLogOn()) {
if (e.getLogPrefix() == LogTags.LOG_PREFIX_ALLOCATION) {
EventAllocation eA = (EventAllocation)e;
Allocation klassAlloc = getAllocation(eA.getAllocClassTag(), eA.getAllocClass());
klassAlloc.allocate(eA.getSize());
Pair p = new Pair(klassAlloc,eA.getSize());
this.objectAlloc.put(eA.getObjectTag(),p);
klassAlloc.addObjectTag(eA.getObjectTag());
} else if (e.getLogPrefix() == LogTags.LOG_PREFIX_FREE) {
EventFree eF = (EventFree)e;
Pair p = this.objectAlloc.remove(eF.getObjectTag());
if (p != null)
p.type.deallocate(p.size);
} else if (e.getLogPrefix() == LogTags.LOG_PREFIX_POINTER) {
EventPointerChange ePC = (EventPointerChange)e;
map(ePC.getObjectClassTag(), ePC.getObjectClassName());
map(ePC.getBeforeClassTag(), ePC.getBeforeClassName());
map(ePC.getAfterClassTag(), ePC.getAfterClassName());
// do some stuff with pointer change here
pointerMutations ++;
}
} else if (e.getLogPrefix() == LogTags.LOG_PREFIX_ALLOCATION) {
EventAllocation eA = (EventAllocation)e;
// just ensure we have mappings
map(eA.getAllocClassTag(), eA.getAllocClass());
getAllocation(eA.getAllocClassTag(), eA.getAllocClass());
}
}
private void map(Long tag, String name) {
if (tag == null || tag == 0) return;
if (tagToClass.containsKey(tag)) {
String className = tagToClass.get(tag);
if ((className == null || className.isEmpty()) && name != null)
tagToClass.put(tag, name);
} else {
tagToClass.put(tag, name);
}
if (name != null && !name.isEmpty() && !classToTag.containsKey(name)) {
classToTag.put(name, tag);
}
}
private Allocation getAllocation(Long classTag, String className) {
Allocation klassAlloc = this.allocation.get(classTag);
if (klassAlloc == null) {
klassAlloc = new Allocation(this, classTag, className);
this.allocation.put(classTag, klassAlloc);
} else {
if (klassAlloc.getClassName().isEmpty() && className!=null && !className.isEmpty()) {
klassAlloc.setClassName(className);
}
}
return klassAlloc;
}
public void processStop() {
if (this.os != null) {
Allocation.writeHeadings(this.os);
AbstractMap<String, LinkedList<Allocation>> map = new TreeMap<String, LinkedList<Allocation>>();
for(Allocation alloc: allocation.values()) {
String className = tagToClass.get(alloc.getClassTag());
if (className == null) {
className = alloc.getClassName();
} else if (alloc.getClassName().isEmpty()) {
alloc.setClassName(className);
}
LinkedList<Allocation> list = map.get(className);
if (list == null) {
list = new LinkedList<Allocation>();
map.put(alloc.getClassName(), list);
}
list.add(alloc);
}
for(String key: map.keySet()) {
LinkedList<Allocation> list = map.get(key);
for(Allocation alloc: list)
alloc.write(this.os);
}
os.write("TOTAL");
os.write("");
os.write(""+this.totalAllocation);
os.write(""+this.currentAllocation);
os.write(""+this.negativeTagCount);
os.write(""+this.totalObjects);
os.write(""+this.currentObjects);
os.write(""+this.pointerMutations);
os.eol();
}
}
public void allocate(Long size) {
totalAllocation += size;
currentAllocation += size;
totalObjects ++;
currentObjects ++;
}
public void deallocate(Long size) {
currentAllocation -= size;
currentObjects --;
}
public void addObjectTag(Long objectTag) {
if (objectTag < 0)
negativeTagCount --;
}
}
}
\ No newline at end of file
package org.dacapo.analysis.thread;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
public class CommandLineArgs {
public static final String DEFAULT_CLASSPATH = "store";
public static final String DEFAULT_LOG_FILE = "log_file";
public static final String OPT_LOG_FILE = "logfile";
public static final String OPT_HELP = "help";
public static final String OPT_OUTPUT_FILE = "output";
public static final String OPT_LOCK_LOG_FILE = "locklogfile";
public static final String STDOUT_NAME = "-";
public static final int EXIT_BAD_COMMANDLINE = 1;
private static final Option[] OPTIONS = {
makeOption("f", OPT_LOG_FILE, "specify the log file", "log_file"),
makeOption("l", OPT_LOCK_LOG_FILE, "specify the lock log file", "lock_log_file"),
makeOption("o", OPT_OUTPUT_FILE, "output CSV file for metrics", "output"),
makeOption("h", OPT_HELP, "help", null)
};