skip to Main Content

I am using the Salabim package in python to simulate some queueing theory. Salabim (documentation) is based on SimPy but with many extensions and additional features.
Most of my problems are solved in a few minutes with minimal memory requirements.

However, I want to extend the model and noted that the simulation captures about 32GB after 1 hour of simulation of a simple M/M/1 queueing problem. I expect this is due to some internal monitors capturing statistical data. I have tried to deactivate most of them but till now without success.

– What statement am I missing?
– What can I change to minimize memory requirements?

Please note that I switch of monitoring for each class with the following code:

    def setup(self):
        self.mode.monitor(False)
        self.status.monitor(False) # added 17 nov, salabim team tip

Code

# passivate/activate method
# https://www.salabim.org/manual/Modelling.html#a-bank-example

import salabim as sim


class CarGenerator(sim.Component):
    def setup(self):
        self.mode.monitor(False)
        self.status.monitor(False) # added 17 nov, salabim team tip

    def process(self):
        while True:
            Car()
            self.hold(iat_distr.sample())


class Car(sim.Component):
    def setup(self):
        self.mode.monitor(False)
        self.status.monitor(False) # added 17 nov, salabim team tip

    def process(self):
        self.enter(waitingline)
        for ChargingStation in ChargingStations:
            if ChargingStation.ispassive():
                ChargingStation.activate()
                break  # activate at most one charging station
        self.passivate()


class ChargingStation(sim.Component):
    def setup(self):
        self.mode.monitor(False)
        self.status.monitor(False)  # added 17 nov, salabim team tip

    def process(self):
        while True:
            while len(waitingline) == 0:
                self.passivate()
            self.car = waitingline.pop()
            self.hold(srv_distr.sample())
            self.car.activate()


N_STATION = 1
iat_distr = sim.Exponential(60 / 40)
srv_distr = sim.Exponential(60 / 50)

# https://www.salabim.org/manual/Reference.html#environment
app = sim.App(
    trace=False,  # defines whether to trace or not
    random_seed="*",  # if “*”, a purely random value (based on the current time)
    time_unit="minutes",  # defines the time unit used in the simulation
    name="Charging Station",  # name of the simulation
    do_reset=True,  # defines whether to reset the simulation when the run method is called
    yieldless=True,  # defines whether the simulation is yieldless or not
)

# Instantiate and activate the client generator
CarGenerator(name="Electric Cars Generator")

# Create Queue and set monitor to stats_only
waitingline = sim.Queue(name="Waiting Cars", monitor=False)
waitingline.length_of_stay.monitor(value=True)
waitingline.length_of_stay.reset_monitors(stats_only=True)

# Instantiate the servers, list comprehension but only 1 server
ChargingStations = [ChargingStation() for _ in range(N_STATION)]

# Execute Simulation
app.run(till=sim.inf)

# Print statistics
waitingline.length_of_stay.print_statistics()

Environment

I am running 'CPython' with python version 3.9.18 and SALABIM version 23.3.11.1 on Ubuntu 22.04 on a Windows Subsystem for Linux (but same happens on a pure Ubuntu 22.04 system)

WSL version: 1.2.5.0
Kernel version: 5.15.90.1
WSLg version: 1.0.51
MSRDC version: 1.2.3770
Direct3D version: 1.608.2-61064218
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.19045.3693

Packages

The following ENV.yml file can be used to recreate the conda environment or check package versions.

name: mem_salabim
channels:
  - conda-forge
  - nodefaults
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=2_gnu
  - anyio=4.0.0=pyhd8ed1ab_0
  - argon2-cffi=23.1.0=pyhd8ed1ab_0
  - argon2-cffi-bindings=21.2.0=py39hd1e30aa_4
  - arrow=1.3.0=pyhd8ed1ab_0
  - asttokens=2.4.1=pyhd8ed1ab_0
  - async-lru=2.0.4=pyhd8ed1ab_0
  - attrs=23.1.0=pyh71513ae_1
  - babel=2.13.1=pyhd8ed1ab_0
  - backports=1.0=pyhd8ed1ab_3
  - backports.functools_lru_cache=1.6.5=pyhd8ed1ab_0
  - beautifulsoup4=4.12.2=pyha770c72_0
  - bleach=6.1.0=pyhd8ed1ab_0
  - brotli-python=1.1.0=py39h3d6467e_1
  - bzip2=1.0.8=hd590300_5
  - ca-certificates=2023.7.22=hbcca054_0
  - cached-property=1.5.2=hd8ed1ab_1
  - cached_property=1.5.2=pyha770c72_1
  - certifi=2023.7.22=pyhd8ed1ab_0
  - cffi=1.16.0=py39h7a31438_0
  - charset-normalizer=3.3.2=pyhd8ed1ab_0
  - comm=0.1.4=pyhd8ed1ab_0
  - debugpy=1.8.0=py39h3d6467e_1
  - decorator=5.1.1=pyhd8ed1ab_0
  - defusedxml=0.7.1=pyhd8ed1ab_0
  - entrypoints=0.4=pyhd8ed1ab_0
  - exceptiongroup=1.1.3=pyhd8ed1ab_0
  - executing=2.0.1=pyhd8ed1ab_0
  - fqdn=1.5.1=pyhd8ed1ab_0
  - greenlet=3.0.1=py39h3d6467e_0
  - idna=3.4=pyhd8ed1ab_0
  - importlib-metadata=6.8.0=pyha770c72_0
  - importlib_metadata=6.8.0=hd8ed1ab_0
  - importlib_resources=6.1.1=pyhd8ed1ab_0
  - ipykernel=6.26.0=pyhf8b6a83_0
  - ipython=8.17.2=pyh41d4057_0
  - isoduration=20.11.0=pyhd8ed1ab_0
  - jedi=0.19.1=pyhd8ed1ab_0
  - jinja2=3.1.2=pyhd8ed1ab_1
  - json5=0.9.14=pyhd8ed1ab_0
  - jsonpointer=2.4=py39hf3d152e_3
  - jsonschema=4.19.2=pyhd8ed1ab_0
  - jsonschema-specifications=2023.7.1=pyhd8ed1ab_0
  - jsonschema-with-format-nongpl=4.19.2=pyhd8ed1ab_0
  - jupyter-lsp=2.2.0=pyhd8ed1ab_0
  - jupyter_client=8.6.0=pyhd8ed1ab_0
  - jupyter_core=5.5.0=py39hf3d152e_0
  - jupyter_events=0.9.0=pyhd8ed1ab_0
  - jupyter_server=2.10.0=pyhd8ed1ab_0
  - jupyter_server_terminals=0.4.4=pyhd8ed1ab_1
  - jupyterlab=4.0.8=pyhd8ed1ab_0
  - jupyterlab_pygments=0.2.2=pyhd8ed1ab_0
  - jupyterlab_server=2.25.1=pyhd8ed1ab_0
  - ld_impl_linux-64=2.40=h41732ed_0
  - libffi=3.4.2=h7f98852_5
  - libgcc-ng=13.2.0=h807b86a_3
  - libgomp=13.2.0=h807b86a_3
  - libnsl=2.0.1=hd590300_0
  - libsodium=1.0.18=h36c2ea0_1
  - libsqlite=3.44.0=h2797004_0
  - libstdcxx-ng=13.2.0=h7e041cc_3
  - libuuid=2.38.1=h0b41bf4_0
  - libzlib=1.2.13=hd590300_5
  - markupsafe=2.1.3=py39hd1e30aa_1
  - matplotlib-inline=0.1.6=pyhd8ed1ab_0
  - mistune=3.0.2=pyhd8ed1ab_0
  - nbclient=0.8.0=pyhd8ed1ab_0
  - nbconvert-core=7.11.0=pyhd8ed1ab_0
  - nbformat=5.9.2=pyhd8ed1ab_0
  - ncurses=6.4=h59595ed_2
  - nest-asyncio=1.5.8=pyhd8ed1ab_0
  - notebook=7.0.6=pyhd8ed1ab_0
  - notebook-shim=0.2.3=pyhd8ed1ab_0
  - openssl=3.1.4=hd590300_0
  - overrides=7.4.0=pyhd8ed1ab_0
  - packaging=23.2=pyhd8ed1ab_0
  - pandocfilters=1.5.0=pyhd8ed1ab_0
  - parso=0.8.3=pyhd8ed1ab_0
  - pexpect=4.8.0=pyh1a96a4e_2
  - pickleshare=0.7.5=py_1003
  - pip=23.3.1=pyhd8ed1ab_0
  - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1
  - platformdirs=4.0.0=pyhd8ed1ab_0
  - prometheus_client=0.18.0=pyhd8ed1ab_1
  - prompt-toolkit=3.0.41=pyha770c72_0
  - prompt_toolkit=3.0.41=hd8ed1ab_0
  - psutil=5.9.5=py39hd1e30aa_1
  - ptyprocess=0.7.0=pyhd3deb0d_0
  - pure_eval=0.2.2=pyhd8ed1ab_0
  - pycparser=2.21=pyhd8ed1ab_0
  - pygments=2.16.1=pyhd8ed1ab_0
  - pysocks=1.7.1=pyha2e5f31_6
  - python=3.9.18=h0755675_0_cpython
  - python-dateutil=2.8.2=pyhd8ed1ab_0
  - python-fastjsonschema=2.18.1=pyhd8ed1ab_0
  - python-json-logger=2.0.7=pyhd8ed1ab_0
  - python_abi=3.9=4_cp39
  - pytz=2023.3.post1=pyhd8ed1ab_0
  - pyyaml=6.0.1=py39hd1e30aa_1
  - pyzmq=25.1.1=py39h8c080ef_2
  - readline=8.2=h8228510_1
  - referencing=0.30.2=pyhd8ed1ab_0
  - requests=2.31.0=pyhd8ed1ab_0
  - rfc3339-validator=0.1.4=pyhd8ed1ab_0
  - rfc3986-validator=0.1.1=pyh9f0ad1d_0
  - rpds-py=0.12.0=py39h9fdd4d6_0
  - send2trash=1.8.2=pyh41d4057_0
  - setuptools=68.2.2=pyhd8ed1ab_0
  - six=1.16.0=pyh6c4a22f_0
  - sniffio=1.3.0=pyhd8ed1ab_0
  - soupsieve=2.5=pyhd8ed1ab_1
  - stack_data=0.6.2=pyhd8ed1ab_0
  - terminado=0.18.0=pyh0d859eb_0
  - tinycss2=1.2.1=pyhd8ed1ab_0
  - tk=8.6.13=noxft_h4845f30_101
  - tomli=2.0.1=pyhd8ed1ab_0
  - tornado=6.3.3=py39hd1e30aa_1
  - traitlets=5.13.0=pyhd8ed1ab_0
  - types-python-dateutil=2.8.19.14=pyhd8ed1ab_0
  - typing-extensions=4.8.0=hd8ed1ab_0
  - typing_extensions=4.8.0=pyha770c72_0
  - typing_utils=0.1.0=pyhd8ed1ab_0
  - tzdata=2023c=h71feb2d_0
  - uri-template=1.3.0=pyhd8ed1ab_0
  - urllib3=2.1.0=pyhd8ed1ab_0
  - wcwidth=0.2.10=pyhd8ed1ab_0
  - webcolors=1.13=pyhd8ed1ab_0
  - webencodings=0.5.1=pyhd8ed1ab_2
  - websocket-client=1.6.4=pyhd8ed1ab_0
  - wheel=0.41.3=pyhd8ed1ab_0
  - xz=5.2.6=h166bdaf_0
  - yaml=0.2.5=h7f98852_2
  - zeromq=4.3.5=h59595ed_0
  - zipp=3.17.0=pyhd8ed1ab_0
  - pip:
      - salabim==23.3.11.1
prefix: /home/floris/miniforge3/envs/jads_salabim

2

Answers


  1. Chosen as BEST ANSWER

    Dear Salabim Magicians,

    The core developer of Salabim has suggested a patch which indeed solved the problem completely. I have tested the solution by running this very simple toy example with the patch applied (see below) for over 10 hours simulating 400 Million cars being charged.

    Memory consumption didn't increase at all!!!

    10 hours of simulation memory still stable

    Solution

    elegant and simple with huge impact

    Instead of

    Car()
    

    use

    Car(name="Car")
    

  2. On 28 November 2023 a new version (23.3.12) of Salabim package has been released which solves this issue and doesn’t need the patch anymore as suggested.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search