Vision is generally a light load on a gateway, for most tasks, since all of its user-interface bindings and scripts run on the client machine, not in the gateway itself. Vision gateway load is almost entirely due to tag binding delivery and running DB queries on behalf of the Vision clients. (Charting workloads, especially.)
Which means you should be carefully investigating all of your gateway scripting. Look especially at (mis-)uses of system.util.invokeAsynchronous
and system.util.getGlobals
as likely sources of memory leaks.
IA generally recommends against the use of virtual machines in production when IA native drivers are involved, as hypervisors are notorious about stealing Ignition's idle CPU time to burn on other vCPUs. You have to configure your hypervisor to not do this. (No CPU overcommit on the entire physical hypervisor running your Ignition VMs, at the very least.)