Skip to content

Commit

Permalink
#6: Add mallinfo() statistics support to command line version
Browse files Browse the repository at this point in the history
  • Loading branch information
mblauth committed Aug 11, 2022
1 parent 77d1914 commit c6bb4cd
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 6 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ application {
}

jar {
from('agent/build/libs/') {
include '**.jar'
}
manifest {
attributes(
"Main-Class": application.mainClass.get(),
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/jdump/cli/CommandLineArguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ private void configure() {
if (argList.contains("-T")) configuration.wantThreadDumpForAll();
if (argList.contains("-J")) configuration.wantJfrForAll();
if (argList.contains("-N")) configuration.wantNmtForAll();
if (argList.contains("-M")) configuration.wantMallInfoForAll();
}
setDuration(argList);
setOutputDirectory(argList);
Expand All @@ -57,15 +58,16 @@ private static Optional<String> getLastOf(List<String> argList, String parameter
}

private void showUsageInformation() {
System.out.println("Usage: jdump [-f<folder name>] [-A] [-H] [-J] [-d<duration in seconds>] [-N] [-T]");
System.out.println("Usage: jdump [-f<folder name>] [-A] [-H] [-J] [-d<duration in seconds>] [-N] [-M] [-T]");
System.out.println();
System.out.println("Options:");
System.out.println("start without options to show UI, if not on a headless system");
System.out.println("-f<name>: name of the target folder (will be created if non-existent; current working directoy, if empty)");
System.out.println("-A: produce all types of dumps for all JVMs running locally");
System.out.println("-A: produce all non-agent-based types of dumps for all JVMs running locally");
System.out.println("-H: produce heap dumps for all JVMs running locally");
System.out.println("-J: produce JFRs for all JVMs running locally");
System.out.println("-d<duration in seconds>: the duration selected for the JFRs, in seconds, default: 5");
System.out.println("-M: produce mallinfo() stats on Linux with glibc");
System.out.println("-N: product Native Memory Tracks for all JVMs running locally");
System.out.println("-T: produce thread dumps for all JVMs running locally");
}
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/jdump/dump/Attach.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package jdump.dump;

import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.*;
import sun.tools.attach.HotSpotVirtualMachine;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* Helper for attaching to JVMs using the Attach API.
*/
class Attach {

static final Map<String, HotSpotVirtualMachine> attachedVMs = new HashMap<>();

/**
Expand Down Expand Up @@ -47,4 +48,14 @@ static synchronized void detachAll() {
attachedVMs.clear();
}

public synchronized static void loadAgent(VirtualMachineDescriptor vmd, String outputFileName) throws
AgentLoadException, IOException, AgentInitializationException {
if (!attachedVMs.containsKey(vmd.id())) throw new RuntimeException("JVM not attached");
// TODO: Remove hard-coded references to agent versions
try (var stream = Attach.class.getResourceAsStream("/agent-1.0-SNAPSHOT.jar")) {
File tempFile = File.createTempFile("agent-1.0-SNAPSHOT-", ".jar");
Files.copy(Objects.requireNonNull(stream), tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
attachedVMs.get(vmd.id()).loadAgent(tempFile.getAbsolutePath(), outputFileName);
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/jdump/dump/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Configuration {
private String outputDirectory = System.getProperty("user.dir");
private Output.TYPE outputType = Output.TYPE.DIRECTORY;
private boolean immutable;
private boolean wantMallInfoForAll = false;

private Configuration() {
immutable = true;
Expand All @@ -32,6 +33,7 @@ private Configuration(Configuration configuration) {
this.wantNmtForAll = configuration.wantNmtForAll;
this.outputDirectory = configuration.outputDirectory;
this.outputType = Output.TYPE.DIRECTORY;
this.wantMallInfoForAll = configuration.wantMallInfoForAll;
immutable = true;
}

Expand Down Expand Up @@ -83,6 +85,14 @@ public Mutable outputType(Output.TYPE outputType) {
super.outputType(outputType);
return this;
}

public void wantMallInfoForAll() {
super.wantMallInfoForAll();
}
}

private void wantMallInfoForAll() {
this.wantMallInfoForAll = true;
}

private void outputType(Output.TYPE outputType) {
Expand Down Expand Up @@ -129,6 +139,10 @@ public boolean nmtForAllSet() {
return wantNmtForAll;
}

public boolean mallInfoForAllSet() {
return wantMallInfoForAll;
}

public String outputDirectory() {
return outputDirectory;
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/jdump/dump/Dumps.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static void handle(Configuration configuration) {
if (configuration.threadDumpForAllSet()) new ThreadDump(configuration).performForAll();
if (configuration.jfrForAllSet()) new JFRDump(configuration).performForAll();
if (configuration.nmtForAllSet()) new NMTDump(configuration).performForAll();
if (configuration.mallInfoForAllSet()) new MallInfoDump(configuration).performForAll();
}

/**
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/jdump/dump/MallInfoDump.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package jdump.dump;

import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachineDescriptor;

import java.io.File;
import java.io.IOException;

public class MallInfoDump extends HotspotDump {
final Configuration configuration;


public MallInfoDump(Configuration configuration) {
this.configuration = configuration;
}


@Override
void performFor(VirtualMachineDescriptor vmd) {
try {
Attach.to(vmd);
} catch (IOException | AttachNotSupportedException e) {
throw new RuntimeException("Could not attach to JVM " + vmd.id());
}
try {
System.out.println("Dumping mallinfo() statistics for JVM " + vmd.id());
Attach.loadAgent(vmd, configuration.outputDirectory() + File.separator + filenameFor(vmd));
} catch (AgentLoadException | IOException | AgentInitializationException e) {
throw new RuntimeException("Failed to load agent: " + e);
}
}

@Override
String filenameFor(VirtualMachineDescriptor vmd) {
return "jdump-mallinfo-" + vmd.id() + ".txt";
}
}

0 comments on commit c6bb4cd

Please sign in to comment.