# Garbage collection for scripts

**URL:** <https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627>\
**Category:** Ignition\
**Created:** [July 13, 2020, 6:20am UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627 "2020-07-13T06:20:08Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 13, 2020, 6:20am UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/1 "2020-07-13T06:20:09Z")

</div>

How does garbage collection for gateway or client scripts work? Does it use same heap as Java's heap and JAVA's garbage collector? For example if you are doing lot of string manipulation such as splitting , concatenation of strings in gateway/client scripts in a cyclic loop every few seconds, then it will obviously result in a lot of garbage memory as strings are immutable in Python as in JS. Will this be handled properly by the garbage collector? What precautions do we have to ensure there are no memory leaks from the scripts?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 13, 2020, 1:24pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/2 "2020-07-13T13:24:49Z")

</div>

Jython objects are java objects and are managed by java’s garbage collector.

There are two major sources of memory leaks, triggered by project updates:

1. Persistent background threads that monitor sockets or serial ports or otherwise stay running for special reasons. They will keep running old code. You must use some mechanism (tag or client tag) to signal such threads that they’ve been replaced and need to shut themselves down.

2. Jython implementations of java Listeners of various types. These will retain their old code until deliberated replaced. Or the event source ceases to exist–the listeners are cleaned up at that point.

I used to recommend the dictionary from system.util.getGlobals() as a safe place to track other objects through restarts. I now recommend my free [Life Cycle](http://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/14) module as a replacement.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 13, 2020, 4:49pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/3 "2020-07-13T16:49:00Z")

</div>

> [@pturmel](#):
>
> Persistent background threads that monitor sockets or serial ports or otherwise stay running for special reasons. They will keep running old code. You must use some mechanism (tag or client tag) to signal such threads that they’ve been replaced and need to shut themselves down.

What if the the sockets that are waiting for inputs on a system.a separate tread on a util.invokeAsynchronous call ?

> [@pturmel](#):
>
> Jython implementations of java Listeners of various types. These will retain their old code until deliberated replaced. Or the event source ceases to exist–the listeners are cleaned up at that point.

Too far fetched from my use case in mind. I want to specifically know the impact of strings routines like split and concatenate point of view..

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 13, 2020, 7:50pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/4 "2020-07-13T19:50:03Z")

</div>

> [@prafull\_j](#):
>
> What if the the sockets that are waiting for inputs on a system.a separate tread on a util.invokeAsynchronous call ?

That is precisely the kind of thread you need to replace. Usually by closing the socket. (If a python socket, you _ **must** _ close it to replace it.) Let the replacement thread open the socket fresh. Use of Thread.interrupt() can help implement this.

> [@prafull\_j](#):
>
> Too far fetched from my use case in mind.

Ok. You asked. I hope you recall it when implementing a listener, as they are all over Ignition's infrastructure.

> [@prafull\_j](#):
>
> I want to specifically know the impact of strings routines like split and concatenate point of view…

Yup. They create garbage that needs to be collected. Regardless whether done by java or jython. No special handling required.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 14, 2020, 5:53am UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/5 "2020-07-14T05:53:08Z")

</div>

Ok, got it. So sockets, threads, listeners and resources in general are the major things that could lead to memory leakage in scripts. Garbage resulting from string functions are automatically taken of by Java's garbage collector.

I am experiencing a situation that whenever I put my development computer (Windows 10) in hibernate mode, and restart (wake it up) it the next day, the system generally reboots in most of the cases whenever I have run my ignition trial version, with my scripts running for sometime (say 30 mins to couple of hours) before the hibernation! I thought is its due to some memory leaks resulting from my gateway scripts! Of course a production server will never go to hibernation.

I had asked this question before also, under what circumstances can a windows machine (with Ignition and designer running on it) reboot after waking from a hibernate state ? If I don't start Ignition , just do some normal browsing or MS office work, the system wakes up quickly without roboot after hibernate! Has anyone experienced this behavior ? Can I see some where on any Ignition dash boards or logs, that will give me an idea about the cause of system reboot ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 14, 2020, 12:33pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/6 "2020-07-14T12:33:53Z")

</div>

No idea. Probably should be a new topic. I don’t use Windows for Ignition development, so I have nothing to suggest. FWIW, I suspend and resume my laptop every day, and any of its VMs containing Ignition Gateways suspend and resume with it just fine. Kubuntu 18.04 hypervisor w/ a multitude of Ubuntu Server LTS VMs.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 14, 2020, 12:42pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/7 "2020-07-14T12:42:25Z")

</div>

Thanks a lot. I guess there is some issue with my laptop HW. I have 4GB RAM but upgraded to I think 12GB, all patches are uptodate and defender firewall and antivirus are in place. Guess I should try development on ubuntu on a separate laptop. Thanks a ton.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 15, 2020, 12:19pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/8 "2020-07-15T12:19:55Z")

</div>

> [@pturmel](#):
>
> That is precisely the kind of thread you need to replace. Usually by closing the socket. (If a python socket, you _ **must** _ close it to replace it.) Let the replacement thread open the socket fresh. Use of Thread.interrupt() can help implement this.

I call util.invokeAsynchronous on rising edge of a tag change event triggered by a user, in a gateway script where I open a socket waiting for a client to connect. The communication goes on well after a client connects. On reset of this tag by user, or in the event of an error on socket (such as client disconnects) , I close the socket on manual close or on exception as the case may be , but the do nothing with the thread. To restart the communication again after that, the user resets and sets the tag, and the invokeAsynchronous is called again and cycle repeats. This works just fine, but will repeated set/reset of the tag cause any thread issues? It has never caused any problems while running in a single run (I might have set/reset the comm 40 to 50 times in a run) , but will it cause build up of any resource leakage, which manifests later? Do I have to close the thread created by invokeAsynchronous call in my scripts explicitly? How do I do that? Which function do I call?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 15, 2020, 1:51pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/9 "2020-07-15T13:51:12Z")

</div>

> [@prafull\_j](#):
>
> Which function do I call?

You quoted the answer. Your async threads need to regularly check for interrupted status.

Also, I strongly recommend you properly implement a listening socket that accepts() runtime sockets. Then you have no need for a trigger tag.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 16, 2020, 12:01pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/10 "2020-07-16T12:01:54Z")

</div>

> [@pturmel](#):
>
> runtime sockets

how to do that in scripts? I don't want to to do it thru modules?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 16, 2020, 12:11pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/11 "2020-07-16T12:11:47Z")

</div>

Use an asynchronous thread with a [ServerSocket](https://docs.oracle.com/javase/8/docs/api/java/net/ServerSocket.html) to listen for connections. Wait for client connections with `.accept()`. Pass the new socket returned from `.accept()` to a new asynchronous thread that implements your actual protocol traffic. Both the listening thread and the protocol work thread should check for a thread interrupt regularly.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 16, 2020, 12:28pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/12 "2020-07-16T12:28:13Z")

</div>

> [@pturmel](#):
>
> Use an asynchronous thread with a [ServerSocket](https://docs.oracle.com/javase/8/docs/api/java/net/ServerSocket.html) to listen for connections. Wait for client connections with `.accept()` . Pass the new socket returned from `.accept()` to a new asynchronous thread that implements your actual protocol traffic.

In fact that's what I am doing, but the asynchronous thread is opened manually by a tag change event! I can put it in gateway start up script to automatically start it, but I wanted to avoid automatic creation.

> [@pturmel](#):
>
> Both the listening thread and the protocol work thread should check for a thread interrupt regularly.

I can still implement it in this on existing implementation.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 17, 2020, 4:58pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/13 "2020-07-17T16:58:03Z")

</div>

> [@prafull\_j](#):
>
> I had asked this question before also, under what circumstances can a windows machine (with Ignition and designer running on it) reboot after waking from a hibernate state ?

What is the impact of running the scripts with tag change events such as the socket script or tag change event script , without Ignition running , i.e. trial mode not reset. The scripts seem to work fine, such as changing tags , fetching tag values thru scripts. Only the timer scripts don't work in server freeze mode. But does it have an adverse effect on memory leaks etc? I guess the Ignition server running state will only impact the history, the PLC data read/writes, etc but scripts will run normally. Just want to ensure, whether the off line running of scripts (with out the server in run mode) has any adverse impact.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 17, 2020, 5:57pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/14 "2020-07-17T17:57:11Z")

</div>

Gateway event scripts are not supposed to run when trial mode is expired. Long-running threads are not disrupted by the end of trial mode, though. I’m not aware of any particular memory leak potential that would result.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 17, 2020, 6:09pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/15 "2020-07-17T18:09:33Z")

</div>

Ok, but Asyncthreads waiting for an input from sockets , or scripts triggered by a tag change event cannot be termed as long running threads. They are just waiting. I can understand a thread taking long time to complete its execution will not stop on expiry of trial, it will stop only after completion of the running task.

What impact will not updating to latest java version (for Ignition 8) on the system have? I have upgraded to Sun's latest version build 1.8.0\_261-b12. I am still experiencing the reboot problem when ever I run Ignition and hibernate and wake up next time! I wonder if its some compatibility issue with JRE version!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 17, 2020, 6:16pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/16 "2020-07-17T18:16:45Z")

</div>

A thread that is waiting on I/O is still “running”. If it waits on I/O a long time, it is “long-running”.

I don’t have your hibernation problems, and I’m not switching to Windows to find out if I’ll have them, too.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 17, 2020, 6:18pm UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/17 "2020-07-17T18:18:28Z")

</div>

Ok, thanks a million for all the help. I am not expecting you to switch to windows! It was very useful discussion.

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [July 19, 2020, 5:50am UTC](https://forum.inductiveautomation.com/t/garbage-collection-for-scripts/36627/18 "2020-07-19T05:50:49Z")

</div>

I think I found the problem of Windows rebooting after hibernate! I think its due to the designer and the launcher remaining ON while putting the system to sleep. It has nothing to do with scripts or memory/resource leakage in scripts. I used to leave designer running always. Now I exit the designer and launcher before putting system to sleep (hibernate), and next time when I wake the system up, system comes on without rebooting windows! I have to observe it for a few more days/weeks before I conclude, but its better to exit the designer while not is use and before hibernating. Perhaps designer is optimized for better user experience but may not worry much about memory usage and resource optimization in my opinion. I will observe it for few weeks and update on this post.
