Hi,
I am getting an AccessViolationException while calling V8ScriptEngine from a finalizer.
I can reproduce the issue with below code:
____________________________________________________________________________________
```
namespace ClearScriptLoadTest
{
public class ClearScriptWrapper
{
private Microsoft.ClearScript.V8.V8ScriptEngine v8Engine;
public ClearScriptWrapper()
{
this.v8Engine = new Microsoft.ClearScript.V8.V8ScriptEngine(Microsoft.ClearScript.V8.V8ScriptEngineFlags.None);
}
~ClearScriptWrapper()
{
Console.WriteLine("Finalizer called");
v8Engine.Dispose();
}
}
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
ClearScriptWrapper csObj = new ClearScriptWrapper();
GC.Collect();
}
}
}
}
```
____________________________________________________________________________________
__Exception :__
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at RefCount.Increment(RefCount* )
at SharedPtr<V8Context>.=(SharedPtr<V8Context>* , SharedPtr<V8Context>* that)
at Microsoft.ClearScript.V8.V8ContextProxyImpl.~V8ContextProxyImpl()
at Microsoft.ClearScript.V8.V8ContextProxyImpl.Dispose(Boolean A_0)
at Microsoft.ClearScript.V8.V8ContextProxyImpl.Dispose()
at Microsoft.ClearScript.V8.V8ScriptEngine.Dispose(Boolean disposing)
at Microsoft.ClearScript.ScriptEngine.Dispose()
at ClearScriptLoadTest.ClearScriptWrapper.Finalize() in c:\Users\xxxxxx\Doc
uments\Visual Studio 2013\Projects\ClearScriptLoadTest\ClearScriptLoadTest\Progr
am.cs:line 18
It works fine when dispose is deterministic .
regards
```
skpandey
```
Comments: Hi skpandey, Accessing another managed object from a finalizer is generally problematic. According to the [documentation](http://msdn.microsoft.com/en-us/library/system.object.finalize(v=vs.110).aspx) (emphasis added): >The Object.Finalize method does nothing by default, but you should override Finalize only if necessary, and __only to release unmanaged resources__. Additionally: >The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts. What's happening is that, in some cases, `ClearScriptWrapper` is finalized _after_ `ClearScriptWrapper.v8Engine`. This results in the latter being _resurrected_, and it can't handle that. We'll add the appropriate defensive checks, but our recommendation would be for your wrapper to implement the [dispose pattern](http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx). Thanks for reporting this!
I am getting an AccessViolationException while calling V8ScriptEngine from a finalizer.
I can reproduce the issue with below code:
____________________________________________________________________________________
```
namespace ClearScriptLoadTest
{
public class ClearScriptWrapper
{
private Microsoft.ClearScript.V8.V8ScriptEngine v8Engine;
public ClearScriptWrapper()
{
this.v8Engine = new Microsoft.ClearScript.V8.V8ScriptEngine(Microsoft.ClearScript.V8.V8ScriptEngineFlags.None);
}
~ClearScriptWrapper()
{
Console.WriteLine("Finalizer called");
v8Engine.Dispose();
}
}
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
ClearScriptWrapper csObj = new ClearScriptWrapper();
GC.Collect();
}
}
}
}
```
____________________________________________________________________________________
__Exception :__
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at RefCount.Increment(RefCount* )
at SharedPtr<V8Context>.=(SharedPtr<V8Context>* , SharedPtr<V8Context>* that)
at Microsoft.ClearScript.V8.V8ContextProxyImpl.~V8ContextProxyImpl()
at Microsoft.ClearScript.V8.V8ContextProxyImpl.Dispose(Boolean A_0)
at Microsoft.ClearScript.V8.V8ContextProxyImpl.Dispose()
at Microsoft.ClearScript.V8.V8ScriptEngine.Dispose(Boolean disposing)
at Microsoft.ClearScript.ScriptEngine.Dispose()
at ClearScriptLoadTest.ClearScriptWrapper.Finalize() in c:\Users\xxxxxx\Doc
uments\Visual Studio 2013\Projects\ClearScriptLoadTest\ClearScriptLoadTest\Progr
am.cs:line 18
It works fine when dispose is deterministic .
regards
```
skpandey
```
Comments: Hi skpandey, Accessing another managed object from a finalizer is generally problematic. According to the [documentation](http://msdn.microsoft.com/en-us/library/system.object.finalize(v=vs.110).aspx) (emphasis added): >The Object.Finalize method does nothing by default, but you should override Finalize only if necessary, and __only to release unmanaged resources__. Additionally: >The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts. What's happening is that, in some cases, `ClearScriptWrapper` is finalized _after_ `ClearScriptWrapper.v8Engine`. This results in the latter being _resurrected_, and it can't handle that. We'll add the appropriate defensive checks, but our recommendation would be for your wrapper to implement the [dispose pattern](http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx). Thanks for reporting this!