Diagnosing and Resolving Java Application Faults with JVM Tools

Essential Linux Commands for System Inspection

A collection of frequently used commands for system monitoring and maintenance.

System Shutdown, Reboot, and Session Control

Command Purpose
shutdown -h now Power off immediately
shutdown -h +10 Schedule shutdown after 10 minutes
shutdown -h 11:00 Shutdown at 11:00
shutdown -c Cancel a pending shutdown
shutdown -r now Reboot now
reboot Reboot the system
init 6 Reboot (runlevel 6)
init 0 Halt (runlevel 0)
poweroff Power off immediately
halt Halt the machine
sync Flush file system buffers to disk
logout Exit the current shell session

System Information and Performance

Command Purpose
uname -a Display kernel, OS, and CPU details
uname -r Show kernel release
uname -m Print machine hardware name
arch Show architecture
hostname Print the system hostname
who List logged-in users
who am i Display the current user’s login identity
whoami Print effective username
cat /proc/version View Linux version string
cat /proc/cpuinfo Inspect CPU information
cat /proc/loadavg Check system load averages
uptime How long the system has been running
env Print environment variables
lsusb -tv Tree view of USB devices
lspci -tv Tree view of PCI devices
lsmod List loaded kernel modules
grep MemTotal /proc/meminfo Show total physical memory
grep MemFree /proc/meminfo Show free memory
free -m Memory and swap usage in MB
date Print system date and time
cal 2021 Display calendar for 2021
top Dynamic view of processes and resource usage
vmstat 1 20 Sample system status every second, 20 times
iostat Report CPU and I/O statistics
sar -u 1 10 CPU utilization sampled every second, 10 times
sar -d 1 10 Disk performance sampled every second, 10 times

Disks and Partitions

Command Purpose
fdisk -l List all disk partitions
swapon -s Summary of swap areas
df -h Report disk usage in human-readable format
du -sh /dir Estimate the size of a directory
du -sk * | sort -rn Sort files and directories by size (descending)
mount /dev/hda2 /mnt/hda2 Mount a partition
mount -t ntfs /dev/sdc1 /mnt/usbhd1 Mount with explicit filesystem type
mount -o loop *.iso /mnt/cdrom Mount an ISO image
umount -v /dev/sda1 Unmount by device
umount -v /mnt/mymnt Unmount by mount point
fuser -km /mnt/hda1 Forcefully kill processes using a mount (use with care)

Users and Groups

Command Purpose
useradd codesheep Create a new user
userdel -r codesheep Remove a user and home directory
usermod -g group_name user_name Change primary group
usermod -aG group_name user_name Add user to supplementary group
usermod -s /bin/ksh -d /home/codepig -g dev codesheep Modify login shell, home, and group
groups test Show groups of a user
groupadd group_name Create a new group
groupdel group_name Delete a group
groupmod -n new_name old_name Rename a group
su - user_name Switch user with full login environment
passwd Change current user’s password
passwd codesheep Change a specific user’s password
w Show who is logged on and what they are doing
id codesheep Display user identity
last Show last logins
crontab -l List current user’s cron jobs
cut -d: -f1 /etc/passwd List all system users
cut -d: -f1 /etc/group List all system groups

Networking and Process Management

Command Purpose
ifconfig Display network interfaces
ifconfig eth0 Show configuration of a specific interface
route -n Print kernel routing table
netstat -lntp List all listening TCP ports with process info
netstat -antp Show established TCP connections
netstat -lutp Show TCP and UDP socket state
ifup eth0 Activate a network interface
ifdown eth0 Deactivate a network interface
iptables -L List firewall rules
ifconfig eth0 192.168.1.1 netmask 255.255.255.0 Assign an IP address
dhclient eth0 Obtain IP via DHCP
route add -net 0/0 gw Gateway_IP Set default gateway
route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.1.1 Add a static route
route del 0/0 gw Gateway_IP Remove the default gateway
hostname Show or set hostname
host www.example.com DNS lookup
nslookup www.example.com Query DNS records
ps -ef List all processes in full format
ps -ef | grep java Filter processes by name
kill -s name Kill a process by name
kill -s pid Kill a process by PID
top Interactive process viewer

Service Management

Command Purpose
chkconfig --list List runlevel service status
service <name> status Check status of a service
service <name> start Start a service
service <name> stop Stop a service
service <name> restart Restart a service
systemctl status <name> View service state (systemd)
systemctl start <name> Start a service (systemd)
systemctl stop <name> Stop a service (systemd)
systemctl restart <name> Restart a service (systemd)
systemctl enable <name> Enable service at boot
systemctl disable <name> Disable service at boot

File and Directory Operations

Command Purpose
cd <dir> Change directory
cd .. Go up one level
cd Go to home directory
pwd Print working directory
ls List directory contents
ls -l Long listing with details
ls -a Include hidden files
ls -lh Human-readable sizes in long listing
ls -lSr Sort by size (ascending)
tree Show directory tree structure
mkdir <dir> Create a directory
mkdir -p /tmp/dir1/dir2 Create directory hierarchy
rm -f file1 Force remove a file
rmdir dir1 Remove an empty directory
rm -rf dir1 Recursively remove directory and contents
mv old new Rename or move
cp file1 file2 Copy a file
cp -a dir1 dir2 Copy directory recursively
ln -s target link_name Create symbolic link
ln target link_name Create hard link
find / -name file1 Search for a file by name
find / -user user1 Find files owned by a user
locate *.mp4 Quickly locate files by pattern
whereis java Locate binary, source, and manual files
which java Show full path of a command
chmod ugo+rwx dir1 Add read, write, execute for all
chmod go-rwx dir1 Remove all permissions for group/others
chown user1 file1 Change file owner
chgrp group1 file1 Change group ownership

File Viewing and Processing

Command Purpose
cat file1 Display entire file
cat -n file1 Show with line numbers
tac file1 Display file in reverse
less file1 Browse file with backward navigation
head -5 file1 Show first 5 lines
tail -5 file1 Show last 5 lines
tail -f /log/app.log Follow file growth in real time
grep 'error' file.log Search for a pattern
grep '^start' file.txt Match lines beginning with a pattern
sed 's/old/new/g' file.txt Replace all occurrences in a file
sed '/^$/d' file.txt Delete blank lines
sed '/ *#/d; /^$/d' file.txt Remove comments and blanks
sed -n '5,10p' file.txt Print lines 5 through 10
paste file1 file2 Merge lines of two files
sort file1 Sort file contents
comm -12 file1 file2 Show lines common to both files

Archive and Compression

Command Purpose
zip -r archive.zip dir1 Compress directory into ZIP
unzip archive.zip Extract ZIP
tar -czf archive.tar.gz dir1 Create gzipped tarball
tar -xzf archive.tar.gz Extract gzipped tarball
tar -cjf archive.tar.bz2 dir1 Create bzip2 compressed tarball
tar -xjf archive.tar.bz2 Extract bzip2 compressed tarball
gzip filename Compress a file with gzip
gunzip filename.gz Decompress gzip
bzip2 filename Compress with bzip2
bunzip2 filename.bz2 Decompress bzip2

Package Management (RPM, YUM, DPKG, APT)

Command Purpose
rpm -qa List installed RPM packages
rpm -ivh package.rpm Install RPM
rpm -e package Remove RPM
yum install pkg Install a package with YUM
yum update Update all packages
yum remove pkg Remove a package
dpkg -l List installed DEB packages
dpkg -i package.deb Install a DEB
apt-get install pkg Install with APT
apt-get update Refresh package index
apt-get upgrade Upgrade all packages

JVM Diagnostics Toolkit

Built-in JDK Command-Line Tools

jps – List Java Processes

Option Description
jps Show main class names and PIDs
jps -q Output only process IDs
jps -l Display the fully qualified main class name
jps -v Print JVM arguments passed to the process

jstat – Monitor JVM Statistics

Command Description
jstat -gc <vmid> 1000 10 Print GC statistics every second for 10 iterations
jstat -gccause <vmid> 1000 10 Show GC cause alongside statistics
jstat -class <vmid> Class loading/unloading statistics
jstat -gcutil <vmid> Summary of GC utilization
jstat -gcnew <vmid> Young generation GC details
jstat -gcold <vmid> Old generation GC details

jinfo – View and Tune JVM Flags

Command Description
jinfo <pid> Print all configuration information
jinfo -flags <pid> List JVM flags that have been set
jinfo -flag <name> <pid> Print the value of a specific flag
jinfo -flag [+/-]<name> <pid> Enable or disable a manageable flag
jinfo -sysprops <pid> Dump all system properties

Only flags marked as manageable can be changed dynamically. Identify them with: java -XX:+PrintFlagsFinal -version | grep manageable

jmap – Memory Map and Heap Dumps

Command Description
jmap -heap <pid> Print detailed heap configuration and usage
jmap -histo:live <pid> Show histogram of live objects
jmap -finalizerinfo <pid> List objects awaiting finalization
jmap -clstats <pid> Display classloader statistics
jmap -dump:live,format=b,file=heap.hprof <pid> Generate a heap dump

The live option ensures only reachable objects are dumped. To automatically create a heap dump on OutOfMemoryError, use JVM arguments: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path>

jstack – Thread Stack Traces

Command Description
jstack <pid> Print all thread stacks
jstack <pid> > threads.txt Redirect output to file
`jstack grep 0x54ee`
jstack -l <pid> Include locking information

jcmd – All-in-One Diagnostic Command (JDK 7+)

Command Description
jcmd -l List all JVM processes
jcmd <pid> help Display available commands for a process
jcmd <pid> GC.heap_dump heap.hprof Generate a heap dump (preferred over jmap)

GUI Analysis Tools

JConsole

A lightweight monitoring tool that tracks memory, threads, and classes. It connects to local or remote JVMs and is useful for quick health checks and memory leak detection.

VisualVM

A comprehensive visual tool that combines multiple command-line capabilities. It provides CPU profiling, heap dump analysis, thread dump inspection, and plugin support. VisualVM can compare heap dumps and execute OQL (Object Query Language) queries to filter objects:

select s from java.lang.String s where s.value.length >= 100
select file.path.value.toString() from java.io.File file

Eclipse Memory Analyzer (MAT)

A powerful offline heap dump analyzer. Key views:

  • Histogram: shows shallow heap (object’s own memory) and retained heap (total memory freed if the object is collected).
  • Dominator Tree: identifies the largest memory retention paths.

By inspecting a histogram and drilling into references from the top consumers, you can trace suspicious large objects back to application code.

JVM Configuration and Startup Script

Key JVM Parameters

Parameter Meaning
-Xms Initial heap size
-Xmx Maximum heap size (set equal to -Xms to avoid resizing)
-Xmn Young generation size
-XX:SurvivorRatio Ratio of eden / survivor space (e.g., 10 means eden = 10 * survivor)
-XX:NewRatio Ratio of old / young generation (e.g., 3 means old = 3 * young)
-XX:MetaspaceSize Initial metaspace size
-XX:MaxMetaspaceSize Maximum metaspace size
-XX:+HeapDumpOnOutOfMemoryError Automatically create heap dump on OOM
-XX:OnOutOfMemoryError Execute a script on OOM
-XX:ThreadStackSize Thread stack size (recommended 512k – 2048k)

Tuning Principles

  1. Frequent full GC or long pauses often indicate code-level issues (e.g., memory leaks, large objects) rather than misconfigured parameters.
  2. Optimize application logic before adjusting JVM settings.
  3. Analyze GC logs and heap dumps to identify bottlenecks. Target full GC pauses above 1–3 seconds.
  4. Iterate: test on a few instances, compare with baselines, and progressively refine.

Sample Shell Script for Java Applications

The following script supports start, stop, restart, status, and allows overriding heap and metaspace sizes.

#!/bin/bash

DEFAULT_HEAP="1024M"
DEFAULT_METASPACE="256M"

APP_HOME="$(cd "$(dirname "$0")" && pwd)"
APP_JAR="${@: -1}"

usage() {
    echo "Usage: $0 {start|stop|restart|status} [options] <app.jar>"
    echo "Options:"
    echo "  -Heap SIZE          set heap size (default $DEFAULT_HEAP)"
    echo "  -MetaspaceSize SIZE set metaspace size (default $DEFAULT_METASPACE)"
}

is_running() {
    local pid=$(ps -ef | grep "$APP_HOME" | grep "$APP_JAR" | grep -v grep | awk '{print $2}')
    if [ -z "$pid" ]; then
        return 1
    else
        echo "$pid"
        return 0
    fi
}

do_start() {
    local heap=$DEFAULT_HEAP
    local metaspace=$DEFAULT_METASPACE
    local extra_opts=""

    shift
    while [[ $# -gt 1 ]]; do
        case "$1" in
            -D*) extra_opts="$extra_opts $1" ;;
            -Heap) heap="$2"; shift ;;
            -MetaspaceSize) metaspace="$2"; shift ;;
        esac
        shift
    done

    if pid=$(is_running); then
        echo "$APP_JAR is already running (PID $pid)"
        return
    fi

    JVM_OPTS="-server -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
    JVM_OPTS="$JVM_OPTS -Xms$heap -Xmx$heap -XX:MaxMetaspaceSize=$metaspace -XX:MetaspaceSize=$metaspace"
    JVM_OPTS="$JVM_OPTS -Duser.dir=$APP_HOME $extra_opts"
    echo "Starting $APP_JAR with options: $JVM_OPTS"
    nohup java $JVM_OPTS -jar "$APP_JAR" > /dev/null 2>&1 &
}

do_stop() {
    if pid=$(is_running); then
        echo "Stopping $APP_JAR (PID $pid)"
        kill -9 "$pid"
    else
        echo "$APP_JAR is not running"
    fi
}

do_status() {
    if pid=$(is_running); then
        echo "$APP_JAR is running (PID $pid)"
    else
        echo "$APP_JAR is not running"
    fi
}

case "$1" in
    start)   do_start "$@" ;;
    stop)    do_stop ;;
    status)  do_status ;;
    restart) do_stop; do_start "$@" ;;
    *)       usage ;;
esac

Troubleshooting Common Runtime Problems

High CPU Usage

  1. Run top and note the PID of the Java process consuming excessive CPU.
  2. Identify the most active threads inside that process:
    ps -mp <PID> -o THREAD,tid,time
    
  3. Convert the problematic thread ID (decimal) to hexadecimal:
    printf "%x\n" <TID>
    
  4. Use jstack to inspect the thread’s stack trace:
    jstack <PID> | grep -A 50 <hex_tid>
    
    This pinpoints the method that is running hot.

Excessive Memory Consumption

  1. Use top or free -m to confirm high memory usage and record the Java PID.
  2. Optionally, collect a histogram of live objects:
    jmap -histo:live <PID> | head -20
    
  3. For a deeper investigation, generate a heap dump:
    jmap -dump:live,format=b,file=heap.hprof <PID>
    
  4. Open the dump in MAT or VisualVM. Focus on objects with large retained sizes and trace they GC roots to identify leak suspects.

Quick check: if jstat -gc <PID> shows that old generation usage keeps rising even after full GCs, a memory leak is almost certain.

Deadlock Detection

A deadlock causes threads to block indefinitely. The JVM can detect classic lock-order deadlocks automatically.

Example deadlock scenario (rewritten):

public class DeadlockDemo {
    public static void main(String[] args) {
        Object resourceX = new Object();
        Object resourceY = new Object();
        new Thread(new Task("Worker-1", resourceX, resourceY)).start();
        new Thread(new Task("Worker-2", resourceY, resourceX)).start();
    }
}

class Task implements Runnable {
    private final String name;
    private final Object first;
    private final Object second;

    public Task(String name, Object first, Object second) {
        this.name = name;
        this.first = first;
        this.second = second;
    }

    @Override
    public void run() {
        synchronized (first) {
            System.out.println(name + " locked " + first);
            try { Thread.sleep(50); } catch (InterruptedException ignored) {}
            synchronized (second) {
                System.out.println(name + " locked " + second);
            }
        }
    }
}

Detection steps:

  1. Obtain the Java PID with jps -l.
  2. Run jstack <PID>. The output will include a section like:
    Found one Java-level deadlock:
    =============================
    "Worker-2":
      waiting to lock monitor ... (held by "Worker-1")
    "Worker-1":
      waiting to lock monitor ... (held by "Worker-2")
    
  3. The stack frames directly above point to the deadlocked lines in your code.

Memory Leak Analysis

Memory leaks prevent the garbage collector from reclaiming unused objects. Common causes:

  • Unclosed resources (streams, connections)
  • Large caches without eviction
  • Incorrect scope of references

Investigation approach:

  • Use jstat -gc <PID> to confirm a steady increase in old generation usage after full GC.
  • Take a heap dump and load it into MAT.
  • In MAT’s histogram, sort by retained heap and inspect the dominator tree for objects that hold an unexpectedly large share of memory.
  • Follow the reference chain back to application classes to identify the leaking code path.

Tags: java JVM Performance Tuning troubleshooting Linux Commands

Posted on Fri, 05 Jun 2026 17:20:46 +0000 by morphius