jar tf <file.jar>
Result:
META-INF/MANIFEST.MF META-INF/JBOSSCOD.SF META-INF/JBOSSCOD.RSA META-INF/ org/ org/apache/ org/apache/log4j/ org/apache/log4j/chainsaw/ [...] org/apache/log4j/Appender.class org/apache/log4j/AppenderSkeleton.class org/apache/log4j/AsyncAppender$DiscardSummary.class org/apache/log4j/AsyncAppender$Dispatcher.class [...] org/apache/log4j/spi/LoggingEvent.class [...]
javap -classpath log4j-boot.jar org.apache.log4j.spi.LoggingEvent
If you want protected and private members, or more informations, you can use additional options.
Result:
Compiled from "LoggingEvent.java"
public class org.apache.log4j.spi.LoggingEvent extends java.lang.Object implements java.io.Serializable{
public final transient java.lang.String fqnOfCategoryClass;
public final java.lang.String categoryName;
public transient org.apache.log4j.Priority level;
public final long timeStamp;
static final long serialVersionUID;
static final java.lang.Integer[] PARAM_ARRAY;
static final java.lang.String TO_LEVEL;
static final java.lang.Class[] TO_LEVEL_PARAMS;
static final java.util.Hashtable methodCache;
static java.lang.Class class$org$apache$log4j$Level;
public org.apache.log4j.spi.LoggingEvent(java.lang.String, org.apache.log4j.Category, org.apache.log4j.Priority, java.lang.Object, java.lang.Throwable);
public org.apache.log4j.spi.LoggingEvent(java.lang.String, org.apache.log4j.Category, long, org.apache.log4j.Priority, java.lang.Object, java.lang.Throwable);
public org.apache.log4j.spi.LocationInfo getLocationInformation();
public org.apache.log4j.Level getLevel();
[...]
static {};
}
To list all the members (even private) of all the classes in a jar you can use this command:
JARNAME=<jarname.jar> sh -c 'jar tf "${JARNAME}" | egrep "\.class$" | sed "s/\.class//g; s/\//\./g" | xargs javap -private -classpath "${JARNAME}"'
Result:
// JARNAME=nashorn.jar sh -c 'jar tf "${JARNAME}" | egrep "\.class$" | sed "s/\.class//g; s/\//\./g" | xargs javap -private -classpath "${JARNAME}"'
Compiled from "ScriptObjectMirror.java"
public final class jdk.nashorn.api.scripting.ScriptObjectMirror extends jdk.nashorn.api.scripting.AbstractJSObject implements javax.script.Bindings {
private static final java.security.AccessControlContext GET_CONTEXT_ACC_CTXT;
private final jdk.nashorn.internal.runtime.ScriptObject sobj;
private final jdk.nashorn.internal.objects.Global global;
private final boolean strict;
private final boolean jsonCompatible;
static final boolean $assertionsDisabled;
private static java.security.AccessControlContext getContextAccCtxt();
public boolean equals(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public java.lang.Object call(java.lang.Object, java.lang.Object...);
[...]
}
To monitor the garbage collection on <pid> every 5 seconds:
jstat -gc <pid> 5s
Proof-of-concept of a script for visualizing it in the command line (requires gnuplot):
#!/bin/bash
set -eu
set -o pipefail
FILENAME="jstat.txt"
NUMBER_OF_LINES=10
cat <(head -n 1 "${FILENAME}") <(tail -n +2 "${FILENAME}" | tail -n "${NUMBER_OF_LINES}") | \
(
cat > /dev/shm/mytempfile && trap 'rm /dev/shm/mytempfile' EXIT && \
gnuplot -e "set terminal dumb; set key autotitle columnhead; plot for[col=1:17] '/dev/shm/mytempfile' using 0:col with lines"
)
jmap -dump:format=b,file=<filename.hprof> <pid>
The memory dump can be analyzed using Eclipse Memory Analyzer