I profile running Java applications often with VisualVM but it needs X to run on the machine.
I know I can connect through management port but that will be an offlin
One way to profile an "already started" JVM is to aggregate multiple jstacks taken over time.
You can for instance parse and display them as a FlameGraph (see details at the various answers for that link, I won't redundantly include them here).