尝试读取或写入受保护的内存。这通常表示其他内存已损坏

我希望有人能告诉我是什么导致了这个错误:

尝试读取或写入受保护的内存。这通常表示其他内存已损坏。

我不能真正发布代码,因为这个错误似乎被抛出在应用程序的任何随机区域。在抛出错误之前,应用程序将运行12-48小时。有时它会停在一个看似随机的地方,抛出上面的错误,其他时候整个应用程序停止,我得到一个屏幕上的错误,说什么“有一个致命的错误在... 这可能是一个错误在 CLR 或...”一些关于 PInvoke 或其他不相关的信息。当这种情况发生时,所有线程都显示已终止,并且没有可用的调试信息。

简而言之,这就是应用程序所做的:

它是一个完全用 C # 编写的多线程服务器应用程序。客户端通过套接字连接到服务器。服务器为客户机运行一个虚拟的“环境”,在这个环境中,客户机可以相互交互,也可以与环境交互。它消耗了相当多的内存,但我没有看到它泄漏。它通常消耗大约1.5 GB。我不认为它泄漏,因为内存使用保持相对恒定的整个应用程序运行时间。它不断运行代码来维护环境,即使客户端什么也不做。它不使用第三方软件或其他 API。此应用程序使用的唯一外部资源是套接字连接和 SQL 数据库连接。它运行在64位服务器上。我已经尝试在 VS2008和 VS2010中使用。Net 2.0、3.5和4.0以及多个服务器上,问题最终还是会出现。

我试过关闭编译器优化和几个微软修补程序。似乎没有什么能解决这个问题。如果任何人知道任何可能的原因,或某种方式来确定什么引起了问题,我们将不胜感激。

455442 次浏览

这个问题几乎总是一个简单的问题。密码不好。它很少是工具,只是从统计分析。每天有数以百万计的人在使用 Visual Studio,也许还有一些人在使用您的代码——哪一部分代码得到了更好的测试?我保证,如果这是 VS 的问题,我们可能已经发现了。

这个语句的意思是,当您试图访问不属于您的内存时,通常是因为您使用的是来自其他地方的已损坏的指针。这就是为什么它说明了一些迹象。

由于内存损坏,错误的捕获很少接近错误的根本原因。效果和你描述的完全一样,看起来是随机的。你只需要看看常见的罪魁祸首,比如:

  • 未初始化的指针或其他值。
  • 写入缓冲区多于其大小。
  • 不受互斥锁保护的线程共享的资源。

从一个像这样的问题向后查找根本原因是 难以置信困难的,因为在问题的产生和问题的检测之间可能发生了如此多的事情。

我发现最简单的方法是查看 损坏了什么(比如说,一个特定的指针) ,然后手动对代码进行静态分析,看看是什么损坏了它,检查上面所示的常见罪魁祸首。然而,即使这样也不会引发长期的问题链。

我对 VS 不是很熟悉,但是您可能也想了解使用内存跟踪工具(比如 Linux 的 valground)的可能性,看看它是否能够发现任何明显的问题。

您是否尝试过关闭应用程序的 防止数据执行

可能是硬件。这可能是一些复杂的东西... ... 但我会尝试建议,在某些地方,您的线程代码没有使用适当的锁来保护某些集合(比如字典)。

你在运行什么操作系统和服务包?

可验证代码不应该破坏内存,因此存在不安全的情况。是否在任何地方使用不安全的代码,例如在缓冲区处理中?另外,关于 PInvoke 的内容可能并非无关紧要,因为 PInvoke 涉及到向非托管代码和相关封送处理的转换。

我最好的建议是附加到一个崩溃的实例,并使用 WINDBG 和 SOS深入研究崩溃时发生的情况。这不适合胆小的人,但在这一点上,你可能需要拿出更强大的工具来确定到底是哪里出了问题。

最后在 WinDBG 和 SOS 的帮助下找到了这个问题。正在由某个未知的 DLL 引发访问冲突。原来是一个叫做“ Nvidia 网络管理器”的软件导致了这个问题。我已经阅读了无数次这个问题如何可以引起防火墙或杀毒软件,我没有使用任何一个,所以我驳回了这个想法。另外,我假设它不是环境的,因为它发生在使用不同硬件的多个服务器上。原来我测试的所有机器都运行“ NVidia 网络管理器”。我相信它与其余的主板驱动程序一起安装。

希望这对某些人有帮助,因为这个问题已经困扰我的应用程序很长一段时间了。

最近我在更改一个项目的开发服务器时遇到了这个问题。我在声明一个新的 OracleConnection 变量的代码行中得到了这个错误。

在尝试了很多事情之后,包括安装修复程序,我尝试更改参考 Oracle。数据访问和系统。百科。OracleClient 在项目中并且它工作了!

当一个项目被移动到一台新机器上时,我建议您更新在该项目中添加的所有引用。

我也面临同样的问题。我的原则是。NET dll (AutoCAD 扩展)在 AutoCAD 2012中运行。我也在用甲骨文。DataAccess 和我的代码在 ExecuteNonQuery ()期间引发了相同的异常。我很幸运地解决了这个问题。我使用的 ODP 的 net 版本(即 Oracle 的2.x)。数据存取)

此错误不应发生在托管代码中。这可能会解决问题:

转到 VisualStudio 调试器以绕过此异常:

Tools menu -> Options -> Debugging -> General -> Uncheck this option "Suppress JIT optimization on module load"

希望能有所帮助。

我刚刚在 VS 2013中遇到了这个问题。NET 4.5和 MapInfo 动态链接库。原来,问题在于我将 Platform for Build 从 x86更改为 AnyCPU,这足以触发这个错误。把它改回 x86就行了。也许能帮到别人。

好吧,这可能没什么用,只是个传闻,但是..。

这个异常是由我们在项目中使用的一些 Twain32库一致抛出的,但只会发生在我的机器上。

我在互联网上尝试了很多建议的解决方案,但都无济于事... ... 直到我拔掉手机插头(它是通过 USB 接口连接的)。

而且成功了。

结果是 Twain32库试图将我的手机列为与 Twain 兼容的设备,它在这个过程中的某些行为导致了这个异常。

想想看..。

尝试运行这个命令

英特斯温索克复位器

资料来源: https://stackoverflow.com/a/20492181/1057791

我的答案很大程度上取决于你的情况,但我们有一个问题,试图升级一个。NET 应用程序的客户端大于10岁,所以他们可以使其工作在 Windows 8.1。@ Alhazen 的回答对我来说是正确的。该应用程序依赖于客户端不想付费更新的第三方 DLL (Pegasus/Accusoft ImagXpress)。我们将应用程序重新定位为。NET 4.5,但是每次执行以下代码行时,我们都会收到 AccessViolationException was unhandled消息:

UnlockPICImagXpress.PS_Unlock (1908228217,373714400,1341834561,28447);

为了解决这个问题,我们必须在项目中添加以下生成后事件:

call "$(DevEnvDir)..\tools\vsvars32.bat"
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\editbin.exe" /NXCOMPAT:NO "$(TargetPath)"

这显式指定可执行文件与数据执行预防不兼容。有关详细信息,请参阅 给你

我今天遇到了一个例外,并找到了解决方案。当我试图调试一个单元测试(NUnit)时,它调用了一个抽象类的虚方法。

问题似乎出在.NET 4.5.1的安装上。

我已经下载并安装了.NET 4.5.2(我的项目仍然引用.NET 4.5.1) ,问题已经解决了。

解决办法:

Https://connect.microsoft.com/visualstudio/feedback/details/819552/visual-studio-debugger-throws-accessviolationexception

在我的情况下,文件是打开的,因此是锁定的。

我是在试图使用同样在 Excel 中打开的 LinqToExcel 加载 Excel 文件时得到它的。

这就是我所做的一切

    var maps = from f in book.Worksheet<NavMapping>()
select f;
try {
foreach (var m in maps)
if (!string.IsNullOrEmpty(m.SSS_ID) && _mappings.ContainsKey(m.SSS_ID))
_mappings.Add(m.SSS_ID, m.CDS_ID);
} catch (AccessViolationException ex) {
_logger.Error("mapping file error. most likely this file is locked or open. " + ex);
}

我在 VisualStudio (VS)2010中遇到了这个问题。更有趣的是,我的解决方案中有几种类型的项目,即控制台应用项目、 WPF 应用程序项目、 Windows 窗体应用程序项目等。但是只有当我将 控制台应用类型的项目设置为解决方案的启动项目时,它才会失败。所有的项目都是空的。它们没有添加用户代码或任何第三方程序集作为引用。所有项目都只引用。NET 基类库(BCL) ,它与项目模板本身一起提供。

如何解决这个问题?

转到控制台应用项目的项目属性(或者你可以在解决方案资源管理器中选择项目文件,然后按 Alt + 进来组合键) > 转到 调试 tab > 选中 启用调试器部分下的 启用非托管代码调试复选框(参考屏幕快照) > 点击工具栏中的 软盘按钮来保存项目属性。

enter image description here

我不知道问题的根本原因。我唯一注意到的是,前一天晚上我的机器上安装了很多 Windows 更新。所有的更新主要包括 Office 更新和 OS 更新(超过12篇 KB 文章)。

更新 : VS 2017之后,设置名称已经改为 启用本机代码调试,可以在 调试引擎部分下面找到(参考屏幕截图) :

enter image description here

我也有这个问题。 我使用 Visual Studio 同时运行不同的解决方案,当关闭其他解决方案并只运行目标解决方案时,它工作得很好,没有出现错误。

我在 VB.NET 的一个项目中也出现了同样的错误。在属性页面上检查“ Enable application Framework”为我解决了这个问题。

问题可能是由于项目中的混合生成平台 DLL 造成的。即,您将项目构建到任何 CPU,但是在已经为 x86平台构建的项目中有一些 DLL。由于32位和64位架构的内存映射不同,这些会导致随机崩溃。如果所有的 DLL 都是为一个平台构建的,那么问题就可以解决了。

在 VS1017中,当试图构建一个前一天构建得非常好的项目时,随机得到了这个错误。重新启动电脑修复问题工作(我也运行以下命令事先,不确定是否需要: netsh winsock 重置)

我在一个接受 StringBuilder引用的方法上使用 pcall 时遇到了这个错误。我使用的缺省构造函数显然只能分配16个字节。Windows 试图在缓冲区中放入超过16个字节,导致缓冲区溢出。

而不是

StringBuilder windowText = new StringBuilder(); // Probable overflow of default capacity (16)

使用更大的容量:

StringBuilder windowText = new StringBuilder(3000);

在某些情况下,这种情况可能发生在:

obj = new obj();
...
obj.Dispose();  // <-----------------    Incorrect disposal causes it
obj.abc...

在我的例子中,我必须使用 P/Invoke 引用一个 C/C + + 库,但是我必须确保首先使用 fixed为输出数组分配内存:

[DllImport("my_c_func_lib.dll", CharSet = CharSet.Ansi)]
public static extern unsafe int my_c_func(double input1, double input2, double pinput3, double *outData);


public unsafe double[] GetMyUnmanagedCodeValue(double input1, double input2, double input3)
{
double[] outData = new double[24];


fixed (double* returnValue = outData)
{
my_c_func(input1, input2, pinput3, returnValue);
}


return outData;
}

详情请参阅: https://www.c-sharpcorner.com/article/pointers-in-C-Sharp/

当我在 VisualStudio 中调试我的 C # WinForms 应用程序时发生了这种情况。我的应用程序通过 DllImport 调用 Win32的东西,例如。

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);

运行 VisualStudio“作为管理员”为我解决了这个问题。

我得到了同样的错误消息:

尝试读写受保护的内存。这通常表示其他内存已损坏。

在我的例子中,在清除并重新构建解决方案之后,错误消失了。

在我的案例中,FTDI 实用工具 FT Prog 在扫描 USB 设备时抛出了错误。把我的蓝牙耳机从电脑上拔下来就解决了这个问题。

我在 lambda 表达式上得到了这个错误消息,该表达式使用 Linq 来过滤对象集合。当我检查集合时,我注意到它的成员没有被填充——在 Locals窗口中,展开它们只显示“ ...”。最终问题出现在最初填充集合的存储库方法中—— Dapper 试图自动映射嵌套对象的属性。我修复了 Dapper 查询来处理多映射,并修复了内存错误。

这可能不是上述问题的最佳答案,但我的问题是缓冲区对象的 lock (This)的无效处置语法和用法。事实证明,由于“ using”语法,对象正在从另一个线程处理掉。并且处理锁()属于松散类型。

// wrong lock syntax
lock(this) {
// modify buffer object
}

我把锁换成了

private static readonly object _lockObject = new object();


lock(_lockObject) {
// modify buffer object
}

并使用建议的 C # 处理语法,问题就解决了。

    public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}


protected virtual void Dispose(bool disposing)
{
if (disposed)
return;


if (disposing)
{
// Free any managed objects here
buffer?.Free();
}


disposed = true;
}

我在 IIS 下本地运行.NetFrameworkWebAPI 应用程序时也遇到过同样的问题。

问题在于,我之前已经将 IIS 应用程序池的托管管道模式更新为“经典”模式。设置回“综合”为我修复的问题。

对于 Xamarin 表单,可以将代码包装在

Device.BeginInvokeOnMainThread(() =>
{
//your code
});

当我从错误的线程更新 UI 时,在 UWP 中发生了这种情况。

我有同样的问题,只是因为试图覆盖我的模型,而更新角服务。

var nu: ExtendedUserSettingModel = this.addUserForm1.value;
// nu.createdOn = this.date; //this was what caused the issue

确保不会覆盖任何已写入的数据

确保您没有创建多个时间转换器对象。 您可以使用 singleton 类来创建一个转换器对象,用 < strong > Haukcode.WkHtmlToPdfDotNet 库解决下面的错误

尝试读取或写入受保护的内存。这通常表明其他内存已损坏

enter image description here

如果这么多年过去了,还有人没有找到解决办法,那么这里还有另一个办法:

我有一个.net 网络应用程序接口,并得到这个错误也。

解决方案是看一下 API 项目,在 物业下,改变 “托管管道模式” 改为 整合,而不是 经典

正如许多人所说,造成这一错误的原因有很多。但是,首先也是最重要的原因是,经常用来存储和检索数据的变量或对象会消耗更多的内存。只要找出来,并消除,如果这不是必需的,或使用单独的线程,这样的执行或任何其他想法,如果你得到。