Tomcat's typical per request overhead is ~50µs
It probably isn't Tomcat
It probably is your application
Use a profiler
Java Object Heap
PermGen / Metaspace
Native memory
Stores the object you create
Control size with Xms and Xmx
Garbage collection clean up unused objects
PermGen: Java 7 and earlier
Stores classes
Control size with XX:PermSize and XX:MaxPermSize
Always has a limit
OOME when it is full
Metaspace: Java 8 and later
Stores classes
Control size with XX:MaxMetaspaceSize
Unlimited by default
Uses as much memory as the OS will give it
Code generation
Socket buffers
File descriptors
Thread stacks
Direct memory space
JNI code
JNI allocated memory
Garbage collection
Generally, JVM defaults are fine
Tuning GC should normally be one of the last things you do
Overview
Start from GC roots and identify all live objects
Remove everything else
Compact the live objects
GC time is proportional to live object size
Java object heap size
Throughput
Pause time
Optimise for any 2 at the expense of the third
Set max Java object heap size to 3x to 5x steady state requirement
Displays the state of all threads in a virtual machine
Provides plenty of information about activity and any dead locks
Provides a trace where each thread started to where its current point in execution
Always take at least 3, ~5s apart
Using diff between them can be enlightening
Unix: kill -3 <pid>
Windows: Ctrl + Break
Windows: Service Runner control panel
jstack
nid
is the OS thread ID
List threads using more than 0.0% CPU
ps -eL -o pid,%cpu,lwp | grep -i `ps -ef | grep -v grep | grep java | awk '{print $2}'` | grep -v ' 0.0'
Agree performance targets
Measure (use a profiler)
Identify bottleneck
Fix root cause
Repeat until target is reached
JSP causing CPU usage