hg
author Georges Racinet <georges.racinet@octobus.net>
Fri, 23 Apr 2021 18:30:53 +0200
branchstable
changeset 47010 76ae43d5b1db
parent 46819 d4ba4d51f85f
child 47880 769cd5703b2c
permissions -rwxr-xr-x
repoview: fix memory leak of filtered repo classes The leak occurs in long-running server processes with extensions, and is measured at 110kB per request. Before this change, the contents of the `_filteredrepotypes` cache are not properly garbage collected, despite it begin a `WeakKeyDictionary`. Extensions have a tendency to generate a new repository class for each `localrepo` instantiation. Server processes based on `hgwebdir_mod` will instantiate a new `localrepo` for each HTTP request that involves a repository. As a result, with a testing process that repeatedly opens a repository with several extensions activated (`topic` notably among them), we see a steady increase in resident memory of 110kB per repository instantiation before this change. This is also true, if we call `gc.collect()` at each instantiation, like `hgwebdir_mod` does, or not. The cause of the leak is that the *values* aren't weak references. This change uses `weakref.ref` for the values, and this makes in our measurements the resident size increase drop to 5kB per repository instantiation, with no explicit call of `gc.collect()` at all. There is currently no reason to believe that this remaining leak of 5kB is related to or even due to Mercurial core. We've also seen evidence that `ui.ui` instances weren't properly garbage collected before the change (with the change, they are). This could explain why the figures are relatively high. In theory, the collection of weak references could lead to much more misses in the cache, so we measured the impact on the original case that was motivation for introducing that cache in 7e89bd0cfb86 (see also issue5043): `hg convert` of the mozilla-central repository. The bad news here is that there is a major memory leak there, both with and without the present changeset. There were no more cache misses, and we could see no more memory leak with this change: the resident size after importing roughly 100000 changesets was at 12.4GB before, and 12.5GB after. The small increase is mentioned for completeness only, and we believe that it should be ignored, at least as long as the main leak isn't fixed. At less than 1% of the main leak, even finding out whether it is merely noise would be wasteful. Original context where this was spotted and first mitigated: https://foss.heptapod.net/heptapod/heptapod/-/issues/466 The leak reduction was also obtained in Heptapod inner HTTP server, which amounts to the same as `hgwebdir_mod` for these questions. The measurements done with Python 3.9, similar figures seen with 3.8. More work on our side would be needed to give measurements with 2.7, because of testing server process does not support it.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45830
c102b704edb5 global: use python3 in shebangs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43659
diff changeset
     1
#!/usr/bin/env python3
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
1698
ad4a2eefe4d7 Update copyright notice
Matt Mackall <mpm@selenic.com>
parents: 515
diff changeset
     3
# mercurial - scalable distributed SCM
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46055
diff changeset
     5
# Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     6
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7672
diff changeset
     7
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8225
diff changeset
     8
# GNU General Public License version 2 or any later version.
33896
1900381b6a6e hg: update top-level script to use modern import conventions
Augie Fackler <raf@durin42.com>
parents: 32424
diff changeset
     9
from __future__ import absolute_import
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    10
12661
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    11
import os
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    12
import sys
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    13
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    14
libdir = '@LIBDIR@'
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    15
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    16
if libdir != '@' 'LIBDIR' '@':
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    17
    if not os.path.isabs(libdir):
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    18
        libdir = os.path.join(
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    19
            os.path.dirname(os.path.realpath(__file__)), libdir
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    20
        )
12661
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    21
        libdir = os.path.abspath(libdir)
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    22
    sys.path.insert(0, libdir)
10da5a1f25dd setup/hg: always load Mercurial from where it was installed.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10263
diff changeset
    23
46055
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    24
# Make `pip install --user ...` packages available to the official Windows
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    25
# build.  Most py2 packaging installs directly into the system python
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    26
# environment, so no changes are necessary for other platforms.  The Windows
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    27
# py2 package uses py2exe, which lacks a `site` module.  Hardcode it according
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    28
# to the documentation.
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    29
if getattr(sys, 'frozen', None) == 'console_exe':
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    30
    vi = sys.version_info
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    31
    sys.path.append(
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    32
        os.path.join(
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    33
            os.environ['APPDATA'],
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    34
            'Python',
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    35
            'Python%d%d' % (vi[0], vi[1]),
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    36
            'site-packages',
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    37
        )
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    38
    )
7740d5102760 hg: add user-site to `sys.path` on Windows to allow pip-installed extensions
Matt Harbison <matt_harbison@yahoo.com>
parents: 45830
diff changeset
    39
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    40
from hgdemandimport import tracing
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    41
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    42
with tracing.log('hg script'):
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    43
    # enable importing on demand to reduce startup time
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    44
    try:
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    45
        if sys.version_info[0] < 3 or sys.version_info >= (3, 6):
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    46
            import hgdemandimport
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    47
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    48
            hgdemandimport.enable()
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    49
    except ImportError:
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    50
        sys.stderr.write(
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    51
            "abort: couldn't find mercurial libraries in [%s]\n"
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    52
            % ' '.join(sys.path)
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    53
        )
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    54
        sys.stderr.write("(check your install and PYTHONPATH)\n")
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    55
        sys.exit(-1)
5197
55860a45bbf2 Enable demandimport only in scripts, not in importable modules (issue605)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5178
diff changeset
    56
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    57
    from mercurial import dispatch
43659
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43073
diff changeset
    58
39592
5e78c100a215 hg: wrap the highest layer in the `hg` script possible in trace event
Augie Fackler <augie@google.com>
parents: 34533
diff changeset
    59
    dispatch.run()