问题标签 [unmanaged-memory]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
819 浏览

c# - F# NativePtr.stackalloc 比 C# stackalloc 慢 - 包含反编译代码

继续我的 F# 性能测试。有关更多背景信息,请参见此处:

f# NativePtr.stackalloc in Struct Constructor

F# NativePtr.stackalloc 意外堆栈溢出

现在我有堆栈数组在 F# 中工作。但是,由于某种原因,等效的 C# 大约快 50 倍。我在下面包含了 ILSpy 反编译版本,它似乎只有 1 行是真正不同的(在 stackAlloc 内)。

这里发生了什么?未经检查的算术真的是造成这种巨大差异的原因吗?不知道我怎么能测试这个?

https://msdn.microsoft.com/en-us/library/a569z7k8.aspx

F# 代码

C# 代码

F#版本反编译

C#版本反编译

F# 版本 IL - 字节分配

C# 版本 IL - 字节分配

更新了 F# IL - IntPtr 分配

更新了 C# IL - IntPtr 分配

0 投票
0 回答
677 浏览

.net - 非托管内存只能通过强制 GC 释放,但为什么呢?

我们有一个用 WPF 编写的复杂的内部 GUI 应用程序。有时我们发现直到我们强制才释放本机内存GC.Collect()。这是我们在生产环境中收集的统计数据。

在此处输入图像描述

我们可以看到非托管内存出现峰值,但托管内存使用率保持较低且稳定。

我知道 GC 只会在需要时发生,但是当有大量无人认领的无人管理时,用户确实会感到很慢。当我们手动收集 GC 时,显然更快。GC后可以释放非托管内存,所以我不认为这是内存泄漏。

我也想有一些关于如何识别过程中发生的事情的经验。我们有日志,并从多个用户那里收集了几个具有相同问题的不同日志。不幸的是,我们未能从不同的日志中找到相似性(看起来它会发生并随时开始发生)。

我们也无法在 DEV 或 QA 环境中重现该问题,或者我可以尝试使用 DebugDiag 来跟踪来自不同模块的非托管分配。顺便说一句,没有管理员权限,所以我无法在生产环境中跟踪非托管分配或设置全局标志。

但是我们可以进行完整的内存转储——它是否有助于识别问题(以及如何识别问题)?

0 投票
1 回答
427 浏览

c# - 用非托管内存指针交换固定数组的指针

我正在固定和取消固定:

在 opencl 方法之前和之后,因此数组在计算时不会移动。现在我需要用对齐的非托管数组指针交换后备数组指针,以便对其进行更快的读/写操作。

但我找不到像“更改 gchandle 支持数组指针的值”这样的信息。

我需要类似“交换”方法的东西:

这需要反射来访问和更改该变量吗?还有许多 C# 方法在计算方法中使用这些数组,所以即使在 C# 空间上也会提供更快的速度吗?因此,我试图让 C# 为所有使用“数组”对象的所有内容使用对齐的分配空间,直到我取消固定它为止。

0 投票
2 回答
1197 浏览

c# - 将结构数组序列化为字节 [] - 我的代码有什么问题?

我有一个通用方法,可以使用and将任何struct类型的数组序列化为 s 数组。完整的代码是:byteMarshal.StructureToPtrMarshal.Copy

它在 99.99% 的时间里都能完美运行。但是,对于我的一位 Windows 7 用户,对于某些输入数据,此代码可预见地会导致以下非 .NET 异常:

传递给系统调用的数据区域太小。(来自 HRESULT 的异常:0x8007007A)。

不幸的是,我无权访问用户的机器来附加调试器,即使处理与我的用户完全相同的输入数据,我也无法复制该问题。这只发生在一个用户的机器上并且只发生在某些输入数据上,但在她的机器上每次都会发生相同的输入数据,所以它绝对不是随机的。

该应用程序面向 .NET 4.5。

任何人都可以看到这段代码有什么问题吗?我唯一的猜测是报告的内容与数据结构的实际大小之间存在一些不匹配Marshal.SizeOf,从而导致为结构分配的内存不足。

如果重要的话,这里是发生错误时被序列化的结构(它是由 OCR 产生的字符位置的表示):

正如您所看到的,所有字段的大小都应该始终保持不变,所以我最初分配一个固定长度的非托管内存段来序列化每个字段struct应该不是问题(应该吗?)。

虽然我欢迎替代或改进的序列化方法,但我更感兴趣的是确定这个特定的错误。谢谢!

更新 感谢 TnTnMn 向我指出这char不是 blittable 类型,我在输入中查找 unicode 字符以查看它们是否正确编组。事实证明,他们不是。

对于CharBox { 0x2022, .15782328, .266239136, .164901689, .271627158 },序列化(十六进制)应该是:

22 20 00 00(字符*)

6D 9C 21 3E(左)

7F 50 88 3E(上)

FD DB 28 3E(右)

B7 12 8B 3E (底部)

(* 由于我没有使用显式布局,它填充到四个字节;我现在对自己感到沮丧,因为我不必要地将数据大小增加了 11%...)

相反,它被序列化为:

95 00 00 00(字符)

6D 9C 21 3E(左)

7F 50 88 3E(上)

FD DB 28 3E(右)

B7 12 8B 3E (底部)

所以它将char0x2022 编组为 0x95。碰巧的是,0x2022 Unicode 和 0x95 ANSI 都是项目符号字符。因此,这不是随机的,而是将所有内容编组到 ANSI,我现在记得,如果您不指定CharSet.

好的,所以这至少证实了一些意外的行为正在发生,并进一步为我们提供了一个很好的工作理论,即哪些条件(即结构中的 unicode 字符)可能导致错误。

它没有解释的是为什么这会引发异常,更不用说为什么除了这个用户之外的任何机器上都没有引发异常。至于前者,byte我认为 unciode 与 ANSI 的大小差异与错误消息(“传递给系统调用的数据区域太小”)一致,但非托管缓冲区 - 大小为 , 容纳 4 个完整字节char会比必要的大,而不是更小。为什么 CLR 或操作系统会因为只将 1 个字节写入打算用于 2 且足够大用于 4 的区域而感到不安?

至于后者,我认为用户可能使用的 .NET 版本可能比其他所有人都低,如果她没有获得所有 Windows 7 更新,可能就是这种情况。但我只是在安装了全新 Windows 7 和 .NET 4.5(应用程序支持的最低版本)的 VM 上进行了尝试,但仍然无法重现该错误。我正试图找出她所拥有的 .NET 版本,以防万一是 4.5.1 或其他版本。不过,这似乎是一个远大的目标。

似乎唯一可以确定的方法是将Character成员更改为int(以保持现有数据的填充相同)并仅char在必要时将其转换为,然后查看是否会更改用户机器上的结果。这也是一个很好的机会,可以将每个不同的Marshal调用包装在异常处理程序中,正如 John 建议的那样,看看究竟是哪个导致了错误。

好消息是这是一个相当低优先级的功能,所以即使它继续发生,我也可以让它安全地失败。

会回来汇报的。谢谢大家。

0 投票
1 回答
163 浏览

c# - Dispose 在 Parallel for 中比常规 for 循环慢。为什么?

我已将我原来的问题简化为这个测试。

使用这个类:

我有这两个测试:

ParallelFor 通常需要大约两倍于常规 for 的时间。根据分析器,62%-65% 的执行时间花在了 ParallelFor 的 FreeHGlobal 中。只有 52%-53% 用于 FreeHGlobal 中用于常规用途。

我认为对于现代 RAM 系统,这不会有太大的不同。有没有办法在多个进程中处理大块非托管内存?有没有办法可以将其更改为多线程?

如果我不处理每个进程中使用的 RAM(坏主意,但只是为了测试),Parallel For 的速度是原来的两倍,但是我只能打开其中大约 4-5 个(它们是大量的图像数据)在应用程序崩溃之前的同一时间(正如您所猜测的那样,内存不足异常)。

为什么对单独的对象进行多个 Dispose 操作会减慢速度?

如果这是唯一的选择,我可以让它们保持单线程,但我希望加快速度。

谢谢你。

0 投票
0 回答
314 浏览

wpf - WPF 应用程序内存使用情况

我有一个 WPF 应用程序。在 x86/x64 模式下,启动时(加载其他模块之前)的内存使用量相应为 250/450mb。该内存的一部分(大约 50mb)用于存储在大型对象堆中的资源字典。但最大的部分 -139mb 被非托管内存中的 WindowsCodecs 库消耗。可以吗?我可以通过这个库以某种方式减少内存的使用吗?

0 投票
1 回答
126 浏览

c# - 将 COM 任务分配器内存中的非托管 Unicode 字符串编组到 SecureString

我使用 API 调用来advapi32.dll管理 Windows 保存的凭据,以便自动化某些可以使用保存的凭据的 Windows 应用程序,这工作正常。

我正在尝试更新我的代码以SecureString始终用于密码,因为我不需要在任何时候与密码中包含的文本进行交互,因此如果我的应用程序从不以纯文本形式保存密码,它应该更安全。

我能够将 SecureString 编组到 COM 任务分配器内存以传递给 API 调用:

SecureString但是,当将该信息读回应用程序时,如果不将字符串复制到托管内存中,无论是作为字符串还是字节数组,我都找不到将这种非托管字符串编组回 a 的方法。

有没有一种我忽略的安全方法可以做到这一点?

0 投票
1 回答
95 浏览

c# - 将数组从 C++(非托管代码)检索到 C Sharp 形式(托管)

我在 C++ 中有以下实现(创建了相同的 DLL)

我已经包括

在头文件中。

我尝试用 C-sharp 接收这个。

但我不知道如何在 buttonClick 事件中接收数组。

我很感激这方面的任何帮助。

0 投票
1 回答
2301 浏览

c# - C#使用内存访问非托管数组或 ArraySegment?

随着Memory,SpanArraySegmentC# 7.2 的引入,我想知道是否可以将非托管数组表示为可枚举的对象,它存在于堆上。

后一个要求排除了Span,它基本上完全实现了我想要的:例如

是否可以用ArraySegmentor做同样的事情Memory?他们的构造函数只接受byte[],也许有一些方法可以欺骗 C# 传递 abyte*而不是byte[]?

0 投票
0 回答
277 浏览

c# - Windbg 中的高锁计数!heap -s,接下来我可以做些什么来检测非托管内存泄漏?

我们的PRD小赢服务之一突然暴涨到80+ GB内存几个小时然后又降下来稳定在6+ GB内存,它通常只使用不到200 MB。我在 6+ GB 时抓取了内存转储,然后重新启动服务器,一切恢复正常。我正在调查为什么它会飙升到这么高,以及为什么它稳定在 6GB 以上。

我发现这是一个非托管内存泄漏问题,因为 CLR 堆很小:

但是堆摘要很高,更可疑的是,锁计数很高

然后我做了!heap -flt s 2d0b0

我无法!heap -p -a查看堆栈,因为我没有在 PRD 中启用 gflags。

相反,我正在尝试dc 00000092b7088bb0 L200根据字符串值进行猜测。在第一个卡盘中没有任何意义(2d0b0 373e - 9b845aa0 (39.37)但是在第二个卡盘中( 10d1 41962 - 44eed902 (17.45)),我发现了类似的东西

它看起来像 Oracle 数据库查询日期时间格式字符串。而且我们确实使用 Oracle,我很难相信我们正在泄漏 Oracle 连接,因为这个小服务已经运行了多年,这是第一次发生这种情况。这就是我现在能走多远。

很抱歉这个问题很长,感谢您花时间阅读

总结一下我的问题:

  1. !heap -s 中的锁计数列是什么意思,这看起来像是我可以继续挖掘的问题的指标,请指出我可以阅读的方向或博客。
  2. 那些原始数据字符串是否对您敲响了另一个钟声,而不是 Oracle?你有过类似的问题吗?
  3. 我们确实使用了很多 .net 远程处理。我知道它很旧,我从未深入研究过它。这可能是这个问题的一个因素吗?
  4. 我在 PRD 什么都做不了,我也无法在 DEV/TEST 中重现这个问题,我还有其他方向可以采取吗?