Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Reset gchead and refchain after shutdown#754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
amos402 wants to merge3 commits intopythonnet:masterfromamos402:reset-gc
Closed
Show file tree
Hide file tree
Changes fromall commits
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
69 changes: 69 additions & 0 deletionssrc/runtime/pythonengine.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All@@ -12,11 +13,16 @@ namespace Python.Runtime
/// </summary>
public class PythonEngine : IDisposable
{
private const int NUM_GENERATIONS = 3;

private static DelegateManager delegateManager;
private static bool initialized;
private static IntPtr _pythonHome = IntPtr.Zero;
private static IntPtr _programName = IntPtr.Zero;
private static IntPtr _pythonPath = IntPtr.Zero;
private static IntPtr _refChain = IntPtr.Zero;
private static IntPtr[] _generations;


public PythonEngine()
{
Expand DownExpand Up@@ -169,6 +175,10 @@ public static void Initialize(IEnumerable<string> args, bool setSysArgv = true,
initialized = true;
Exceptions.Clear();

_generations = GetGCGenerations();
#if PYTHON_WITH_PYDEBUG
_refChain = GetRefChainHead();
#endif
// Make sure we clean up properly on app domain unload.
AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;

Expand DownExpand Up@@ -318,6 +328,9 @@ public static void Shutdown()

ExecuteShutdownHandlers();

Runtime.Shutdown();
ResetGC();

initialized = false;
}
}
Expand DownExpand Up@@ -598,6 +611,62 @@ internal static PyObject RunString(string code, IntPtr? globals, IntPtr? locals,
}
}
}

internal static void ResetGC()
{
ClearGC();
#if PYTHON_WITH_PYDEBUG
ResetRefChain();
#endif
}

private static void ClearGC()
{
Debug.Assert(_generations != null);
foreach (IntPtr head in _generations)
{
// gc.gc_next
Marshal.WriteIntPtr(head, 0, head);
// gc.gc_prev
Marshal.WriteIntPtr(head, IntPtr.Size, head);
}
}

private static IntPtr[] GetGCGenerations()
{
int GCHeadOffset = IntPtr.Size == 4 ? 24 : 32;
IntPtr op = Runtime._PyObject_GC_New(Runtime.PyTypeType);
Runtime.PyObject_GC_Track(op);
IntPtr g = Runtime._Py_AS_GC(op);
// According to _PyObjct_GC_TRACK and PyGC_Head strcture, g is the g->gc.gc_next
// It also become the GEN_HEAD(0) now
IntPtr[] gens = new IntPtr[NUM_GENERATIONS];
for (int i = 0; i < NUM_GENERATIONS; i++)
{
gens[i] = g;
g += GCHeadOffset;
}
Runtime.PyObject_GC_UnTrack(op);
Runtime.PyObject_GC_Del(op);
return gens;
}

#if PYTHON_WITH_PYDEBUG
private static void ResetRefChain()
{
Debug.Assert(_refChain != IntPtr.Zero);
Marshal.WriteIntPtr(_refChain, ObjectOffset._ob_next, _refChain);
Marshal.WriteIntPtr(_refChain, ObjectOffset._ob_prev, _refChain);
}

private static IntPtr GetRefChainHead()
{
IntPtr op = Runtime._PyObject_GC_New(Runtime.PyBaseObjectType);
IntPtr refchain = Marshal.ReadIntPtr(op, ObjectOffset._ob_prev);
Runtime.PyObject_GC_Del(op);
return refchain;
}
#endif
}

public enum RunFlagType
Expand Down
6 changes: 5 additions & 1 deletionsrc/runtime/runtime.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1872,7 +1872,7 @@ internal static IntPtr PyType_GenericAlloc(IntPtr type, long n)
internal static extern IntPtr _PyObject_GetDictPtr(IntPtr obj);

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtrPyObject_GC_New(IntPtr tp);
internal static extern IntPtr_PyObject_GC_New(IntPtr tp);

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyObject_GC_Del(IntPtr tp);
Expand DownExpand Up@@ -1907,6 +1907,10 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size)
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern void PyMem_Free(IntPtr ptr);

internal static IntPtr _Py_AS_GC(IntPtr op)
{
return op - IntPtr.Size;
}

//====================================================================
// Python exception API
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp