Skip to content

Commit 66fc91b

Browse files
author
dse
committed
Added PYTHONNET_GC_DEBUG environment variable option for debugging GC related errors.
1 parent a3f26c2 commit 66fc91b

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2424

2525
### Fixed
2626
- Fixed memory leaks, caused by non-working PyObject, PythonException, DelecateManager->Dispatcher finalizers.
27+
Set environment variable PYTHONNET_GC_DEBUG=1 to force full GC on each PythonEngine.Shutdown, this allows
28+
to esily detect GC related bugs.
2729
- Fixed secondary PythonEngine.Initialize call, all sensitive static variables now reseted.
2830
This is a hidden bug. Once python cleaning up enough memory, objects from previous engine run becomes corrupted.
2931
- Fixed Visual Studio 2017 compat (#434) for setup.py

src/runtime/pythonengine.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Reflection;
66
using System.Runtime.InteropServices;
7+
using System.Threading;
78

89
namespace Python.Runtime
910
{
@@ -17,6 +18,12 @@ public class PythonEngine : IDisposable
1718
private static IntPtr _pythonHome = IntPtr.Zero;
1819
private static IntPtr _programName = IntPtr.Zero;
1920
private static IntPtr _pythonPath = IntPtr.Zero;
21+
private static bool _isGcDebugEnabled;
22+
23+
static PythonEngine()
24+
{
25+
_isGcDebugEnabled = !String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("PYTHONNET_GC_DEBUG"));
26+
}
2027

2128
public PythonEngine()
2229
{
@@ -298,9 +305,25 @@ public static void Shutdown()
298305
{
299306
if (initialized)
300307
{
308+
309+
if (_isGcDebugEnabled)
310+
{
311+
GC.Collect();
312+
GC.WaitForPendingFinalizers();
313+
Thread.Sleep(100);
314+
}
315+
301316
CurrentRefDecrementer?.Dispose();
302317
CurrentRefDecrementer = null;
303318

319+
if (_isGcDebugEnabled)
320+
{
321+
GC.Collect();
322+
GC.WaitForPendingFinalizers();
323+
Thread.Sleep(100);
324+
}
325+
326+
304327
PyScopeManager.Global.Clear();
305328
// We should not release memory for variables that can be used without initialized python engine.
306329
// It's assumed that Py_GetPythonHome returns valid string without engine initialize. Py_GetPythonHome will always return the

0 commit comments

Comments
 (0)