There are questions about how perspective-worker is invoked

Now in my project, I have a thread called perspective-worker, and I don't know how it gets called, but it takes up a lot of resources and even causes my server to crash

Perspective uses dynamic thread pools to handle bindings and events throughout its operations. You have to look at the stack trace to see what's going on, but you've cut it off. (Post text in a pre-formatted text block, not screenshots.)

But from the monitors locked, I'm guessing you have a runaway script. (Or a script tasked with something too complex for the amount of gateway RAM available--that will crash your gateway.)

Look for more details to share.

Note there are some configuration parameters you can use to cap or otherwise control the by default unbound thread pool for Perspective workers:

Out of 4513 Perspective-worker threads, the number of threads ① is 724 and threads ② is 3700.
What are these threads used for?


java.base@11.0.18/java.lang.Class.getDeclaredConstructors0(Native Method) java.base@11.0.18/java.lang.Class.privateGetDeclaredConstructors(Unknown Source) java.base@11.0.18/java.lang.Class.getConstructor0(Unknown Source) java.base@11.0.18/java.lang.Class.getConstructor(Unknown Source) app//org.python.core.BytecodeLoader.makeCode(BytecodeLoader.java:251) app//org.python.compiler.LegacyCompiler$LazyLegacyBundle.loadCode(LegacyCompiler.java:43) app//org.python.core.CompilerFacade.compile(CompilerFacade.java:33) app//org.python.core.Py.compile_flags(Py.java:2218) app//org.python.core.Py.compile_flags(Py.java:2223) app//org.python.core.Py.compile_flags(Py.java:2253) app//com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:898) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunctionSuper(ProjectScriptLifecycle.java:789) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.getOrCreateDelegate(ProjectScriptLifecycle.java:888) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.(ProjectScriptLifecycle.java:879) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunction(ProjectScriptLifecycle.java:774) app//com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:881) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.lambda$invoke$0(ScriptFunctionHelper.java:114) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper$$Lambda$7389/0x0000000802335c40.apply(Unknown Source) java.base@11.0.18/java.util.concurrent.atomic.AtomicReference.updateAndGet(Unknown Source) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:107) com.inductiveautomation.perspective.gateway.script.ScriptRunner.run(ScriptRunner.java:38) java.base@11.0.18/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) java.base@11.0.18/java.util.concurrent.FutureTask.run(Unknown Source) java.base@11.0.18/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) java.base@11.0.18/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58) java.base@11.0.18/java.lang.Thread.run(Unknown Source)



java.base@11.0.18/java.lang.ClassLoader.defineClass1(Native Method) java.base@11.0.18/java.lang.ClassLoader.defineClass(Unknown Source) app//org.python.core.BytecodeLoader$Loader.loadClassFromBytes(BytecodeLoader.java:313) app//org.python.core.BytecodeLoader.makeClass(BytecodeLoader.java:37) app//org.python.core.BytecodeLoader.makeCode(BytecodeLoader.java:249) app//org.python.compiler.LegacyCompiler$LazyLegacyBundle.loadCode(LegacyCompiler.java:43) app//org.python.core.CompilerFacade.compile(CompilerFacade.java:33) app//org.python.core.Py.compile_flags(Py.java:2218) app//org.python.core.Py.compile_flags(Py.java:2223) app//org.python.core.Py.compile_flags(Py.java:2253) app//com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:898) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunctionSuper(ProjectScriptLifecycle.java:789) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.getOrCreateDelegate(ProjectScriptLifecycle.java:888) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.(ProjectScriptLifecycle.java:879) app//com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.compileFunction(ProjectScriptLifecycle.java:774) app//com.inductiveautomation.ignition.common.script.ScriptManager.compileFunction(ScriptManager.java:881) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.lambda$invoke$0(ScriptFunctionHelper.java:114) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper$$Lambda$7389/0x0000000802335c40.apply(Unknown Source) java.base@11.0.18/java.util.concurrent.atomic.AtomicReference.updateAndGet(Unknown Source) com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:107) com.inductiveautomation.perspective.gateway.script.ScriptRunner.run(ScriptRunner.java:38) java.base@11.0.18/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) java.base@11.0.18/java.util.concurrent.FutureTask.run(Unknown Source) java.base@11.0.18/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) java.base@11.0.18/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58) java.base@11.0.18/java.lang.Thread.run(Unknown Source)

Both of those stacktraces are involved in compiling your Jython code to run it as a script. That should be a relatively quick operation (on the order of milliseconds) and it should be cached and only performed once per defined script. That you've apparently got thousands of threads doing the same type of work suggests some pathological case that we've never encountered before. I'd strongly suggest contacting our support department.

We observed that when the PLC is powered off and restarted, the number of threads increases to over 20,000 within 3 minutes, which causes the gateway to crash. More than 90% of these threads are Perspective workers. What tasks might these threads be processing? For example, scripts in the View or points bind to the PLC?


We attempted to address the issue by modifying the -Dperspective.threadpool.perspective-worker.pool-size setting to limit the number of threads. However, this did not solve the underlying problem, and we are unsure of what is triggering these threads.

I'd strongly suggest contacting our support department.

Without scanning every stack trace in a thread dump and having your project to compare to, it's literally impossible to say. I don't know, and can't tell you, if you've discovered a bug in Ignition, if you're doing something wrong, if your computer is cursed, or what. You need to provide more information to someone who's getting paid to help you. This forum isn't an official support venue.

4 Likes