Here's the quick and dirty way of using VisualVM's https://visualvm.github.io/ sampler feature to track down a cause of slowdown in Starsector, particularly for mod authors.
There are two ways to monitor the time a method takes: the profiler, which meticulously tracks every single method call and the exact amount of CPU time each uses; and the sampler, which simply asks the Java Virtual Machine which method it's in at a constant rate, and over time uses these samples to estimate how long the JVM spent in each method.
We're using the latter, as accuracy isn't important in our case. If something is indeed causing slowdown then it'll be big and obvious. A profiler is slow and its precision is absolute overkill for our purposes.
Load up Starsector in VisualVM[edit | edit source]
Step one: once you've encountered slowdown, open VisualVM and double click on StarfarerLauncher in the left. The screen will look like this: https://cdn.discordapp.com/attachments/139765881986088960/812870798867169280/unknown.png
Sampler[edit | edit source]
Step two: Click on Sampler at the top of the window, then Sample: CPU. Let the game run for several seconds before pressing stop.
The results will be a tree of method calls sorted by what percentage of CPU time was spent in each method. The game uses several threads (even if the game's actual logic is single-threaded), so you'll have to find the game logic thread in this list. It's usually Thread-4, but if not it'll be whichever thread has com.fs.starfarer.StarfarerLauncher$1.run() listed at the top of the call chain: https://cdn.discordapp.com/attachments/139765881986088960/812872988239593472/unknown.png
[edit | edit source]
Step three: Now it's a case of expanding down that thread's tree until you find a mod script, then continuing to expand until the CPU percentage drops. The last method with a high CPU time will be the problem method. In this contrived example, it'd be checkRebuild(): https://cdn.discordapp.com/attachments/139765881986088960/812876731140145172/unknown.png
Analyse results[edit | edit source]
Step four: Just finding the method doesn't tell you why the method is causing the game to slow down. The cause could be anywhere in the calls above it - all we've learned is which method is using up the frame time. For example, in the above image the slowdown is actually caused by renderInUICoords(), which is deliberately rendering many hundreds of thousands of images simultaneously. So even with a profiler you'll have to manually examine the scripts to find the cause, but profiling will allow you to narrow down the search to only a few places.
Additional[edit | edit source]
Additionally, slowdown can occur in multiple places, especially with combat plugins (which have multiple methods called at different points during the frame). You'll want to keep expanding anything with >20% CPU time just to make sure you didn't miss anything. In the above image, that'd mean also checking com.fs.starfarer.combat.CombatEngine.advance()