Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added PYTHONNET_GC_DEBUG environment variable option for debugging GC…
… related errors.
  • Loading branch information
dse committed Sep 5, 2017
commit 66fc91b9eb946e41d7c355bfa1fbbac73baedf3d
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].

### Fixed
- Fixed memory leaks, caused by non-working PyObject, PythonException, DelecateManager->Dispatcher finalizers.
Set environment variable PYTHONNET_GC_DEBUG=1 to force full GC on each PythonEngine.Shutdown, this allows
to esily detect GC related bugs.
- Fixed secondary PythonEngine.Initialize call, all sensitive static variables now reseted.
This is a hidden bug. Once python cleaning up enough memory, objects from previous engine run becomes corrupted.
- Fixed Visual Studio 2017 compat (#434) for setup.py
Expand Down
23 changes: 23 additions & 0 deletions src/runtime/pythonengine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

namespace Python.Runtime
{
Expand All @@ -17,6 +18,12 @@ public class PythonEngine : IDisposable
private static IntPtr _pythonHome = IntPtr.Zero;
private static IntPtr _programName = IntPtr.Zero;
private static IntPtr _pythonPath = IntPtr.Zero;
private static bool _isGcDebugEnabled;

static PythonEngine()
{
_isGcDebugEnabled = !String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("PYTHONNET_GC_DEBUG"));
}

public PythonEngine()
{
Expand Down Expand Up @@ -298,9 +305,25 @@ public static void Shutdown()
{
if (initialized)
{

if (_isGcDebugEnabled)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(100);
}

CurrentRefDecrementer?.Dispose();
CurrentRefDecrementer = null;

if (_isGcDebugEnabled)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(100);
}


PyScopeManager.Global.Clear();
// We should not release memory for variables that can be used without initialized python engine.
// It's assumed that Py_GetPythonHome returns valid string without engine initialize. Py_GetPythonHome will always return the
Expand Down