forked from dotnet/coreclr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't run finalizers on shutdown, provide Unloading event
API review: dotnet/corefx#5205 This change implements the proposal in the API review above: - Don't block threads for shutdown - Don't run finalizers on shutdown (for both reachable and unreachable objects) - Provide a public AssemblyLoadContext.Unloading event that can be handled to clean up global resources in an assembly - As unloading an AssemblyLoadContext is not yet implemented, the event will for the time being be raised shortly prior to shutdown
- Loading branch information
Showing
8 changed files
with
3,693 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System; | ||
using System.Threading; | ||
|
||
public class FinalizeTimeout | ||
{ | ||
public static int Main(string[] args) | ||
{ | ||
Console.WriteLine("Main start"); | ||
|
||
// Run the finalizer at least once to have its code be jitted | ||
BlockingFinalizerOnShutdown finalizableObject; | ||
do | ||
{ | ||
finalizableObject = new BlockingFinalizerOnShutdown(); | ||
} while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce); | ||
|
||
// Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the | ||
// threads will be blocked for shutdown while holding one of the GC locks | ||
for (int i = 0; i < Environment.ProcessorCount; ++i) | ||
{ | ||
var t = new Thread(ThreadMain); | ||
t.IsBackground = true; | ||
t.Start(); | ||
} | ||
|
||
// Wait a second to give the threads a chance to actually start running | ||
Thread.Sleep(1000); | ||
|
||
Console.WriteLine("Main end"); | ||
|
||
// Create another finalizable object, and immediately return from Main to have finalization occur during shutdown | ||
finalizableObject = new BlockingFinalizerOnShutdown() { isLastObject = true }; | ||
return 100; | ||
} | ||
|
||
private static void ThreadMain() | ||
{ | ||
byte[] b; | ||
while (true) | ||
b = new byte[1024]; | ||
} | ||
|
||
private class BlockingFinalizerOnShutdown | ||
{ | ||
public static bool finalizerCompletedOnce = false; | ||
public bool isLastObject = false; | ||
|
||
~BlockingFinalizerOnShutdown() | ||
{ | ||
if (finalizerCompletedOnce && !isLastObject) | ||
return; | ||
|
||
Console.WriteLine("Finalizer start"); | ||
|
||
// Allocate in the finalizer for long enough to try allocation after one of the background threads blocks for | ||
// shutdown while holding one of the GC locks, to deadlock the finalizer. The main thread should eventually time | ||
// out waiting for the finalizer thread to complete, and the process should exit cleanly. | ||
TimeSpan timeout = isLastObject ? TimeSpan.FromMilliseconds(500) : TimeSpan.Zero; | ||
TimeSpan elapsed = TimeSpan.Zero; | ||
var start = DateTime.Now; | ||
int i = -1; | ||
object o; | ||
do | ||
{ | ||
o = new object(); | ||
} while ((++i & 0xff) != 0 || (elapsed = DateTime.Now - start) < timeout); | ||
|
||
Console.WriteLine("Finalizer end"); | ||
finalizerCompletedOnce = true; | ||
} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<AssemblyName>FinalizeTimeout</AssemblyName> | ||
<ProjectGuid>{3B0E8096-79D4-413F-9010-F68DF90073B5}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<FileAlignment>512</FileAlignment> | ||
<CLRTestPriority>2</CLRTestPriority> | ||
</PropertyGroup> | ||
<!-- Default configurations to help VS understand the configurations --> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="FinalizeTimeout.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="project.json" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"dependencies": { | ||
"System.Diagnostics.Process": "4.0.0-beta-23302", | ||
"System.IO": "4.0.10-beta-23302", | ||
"System.IO.FileSystem": "4.0.0-beta-23302", | ||
"System.IO.FileSystem.Primitives": "4.0.0-beta-23302", | ||
"System.Runtime": "4.0.20-beta-23302", | ||
"System.Runtime.Extensions": "4.0.10-beta-23302", | ||
"System.Runtime.Handles": "4.0.0-beta-23302", | ||
"System.Runtime.Loader": "4.0.0-beta-23302", | ||
"System.Threading": "4.0.10-beta-23302", | ||
"System.Globalization.Calendars": "4.0.0-beta-23302", | ||
"System.Globalization": "4.0.10-beta-23302", | ||
"System.Text.Encoding": "4.0.10-beta-23302", | ||
"System.Runtime.InteropServices": "4.0.20-beta-23302", | ||
"System.Collections": "4.0.10-beta-23302", | ||
"System.Console": "4.0.0-beta-23302", | ||
"System.Reflection": "4.0.10-beta-23302", | ||
"System.Reflection.Primitives": "4.0.0-beta-23302", | ||
"System.ComponentModel": "4.0.1-beta-23302", | ||
"System.Xml.ReaderWriter": "4.0.11-beta-23302", | ||
"System.Collections.NonGeneric": "4.0.1-beta-23302", | ||
"System.Collections.Specialized": "4.0.1-beta-23302", | ||
"System.Linq": "4.0.1-beta-23302", | ||
"System.Linq.Queryable": "4.0.1-beta-23302", | ||
"System.Xml.XmlSerializer": "4.0.11-beta-23302", | ||
"System.Xml.XmlDocument": "4.0.1-beta-23302", | ||
"System.Xml.XDocument": "4.0.11-beta-23302" | ||
}, | ||
"frameworks": { | ||
"dnxcore50": {} | ||
} | ||
} |
Oops, something went wrong.