Win2D 入门教程 VB 中文版 - 防止内存泄漏
避免内存泄漏 |
本文从微软官方文档翻译
http://microsoft.github.io/Win2D/html/RefCycles.htm
如果文档有问题,可以在 https://github.com/Nukepayload2/Win2dDocVB发 Issue,也可以直接回复。
当在托管的 XAML 应用程序中使用 Win2D 控件,需要注意垃圾回收器回收这些控件前它们的引用计数循环。
你有一个问题,如果...
您正在使用 Win2D 从一种.NET 语言如 VB (不是 c + +)
您使用 Win2D XAML 控件之一:
l CanvasControl
l CanvasVirtualControl
l CanvasAnimatedControl
l CanvasSwapChainPanel
l 你订阅 Win2D 控件的事件 (例如 绘制,CreateResources,SizeChanged...)
l 您的应用程序多个 XAML 页之间来回移动
如果满足所有这些条件,引用计数循环将阻止 Win2D 控件被垃圾回收。新的 Win2D 资源分配每次应用程序移动到一个不同的页,但旧的永远不会被释放,所以内存泄漏。要避免此问题,必须添加代码来显式地打破这种循环。
如何修复它
打破引用计数循环,让你的页面进行垃圾回收:
处理Xaml页面或对话框的Unloaded事件
在卸载处理程序,调用 RemoveFromVisualTree Win2D 控件并释放 (通过设置为 Nothing) 对 Win2D 控件的任何显式引用
示例代码:
VB
Private Sub page_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.UnloadedMe.canvas.RemoveFromVisualTreeMe.canvas = NothingEnd Sub
如何测试内存是否泄漏
若要测试是否您的应用程序正确打破引用循环,将代码添加到包含 Win2D 控件的任何 XAML 页或对话框的终结器方法:
VB
Protected Overrides Sub Finalize()Debug.WriteLine("回收画布")MyBase.Finalize()End Sub
在您的应用程序的构造函数建立一个计时器,它将使确定垃圾收集发生在固定的时间间隔:
VB
Dim gcTimer As New DispatcherTimerAddHandler gcTimer.Tick, Sub() GC.CollectgcTimer.Interval = TimeSpan.FromSeconds(1)gcTimer.Start
导航到页面,然后从它到其他页面上。
引用循环打破后大概一秒你会在输出窗口看到 "回收画布"
请注意,调用 GC.Collect 会影响性能,所以您应该在测试后删除此测试代码
残酷的细节
对象 A 引用了 B,同时 B 也引用 A.
这时发生一个循环。或者当 B 和 B 的引用引用 C,而 C 引用 A 等。
当订阅事件的 XAML 控件,这种循环是几乎不可避免:
l XAML 页保留对它所包含的所有控件的引用
l 控件保持对已订阅它们的事件处理程序委托的引用
l 每个委托保存到其目标实例的引用
l 事件处理程序通常是实例方法的 XAML 页类,所以他们目标实例引用点返回到 XAML 页面,创建一个循环
如果在.NET 中实现所有涉及的对象,这种循环不是问题因为.NET 垃圾回收,垃圾回收算法能够识别并回收的对象组,即使它们链接在一个循环中。与.NET不同的是 c + + 管理内存的引用计数,无法检测和回收循环对象。尽管有这种限制,使用 Win2D 的 c + + 应用程序没有任何问题,因为 c + + 事件处理程序默认为弱引用而不是他们的目标实例的强引用。因此页面引用该控件,而控件引用的事件处理程序委托,此委托未引用返回到页面,所以没有任何这种问题。
问题在于当.NET 应用程序使用 c + + WinRT 组件如 Win2D:
l XAML 页是应用程序的一部分,所以使用垃圾回收
l Win2D 控制在 c + + 中实现,因此,使用引用计数
l 事件处理程序委托是应用程序的一部分,所以使用垃圾回收,认为对其目标实例的强引用
一个引用循环是存在的但参加这个的 Win2D 对象不使用.NET 垃圾回收。这意味着垃圾收集器是无法看到整个链,因此它不能检测或回收的对象。当这发生时,应用程序必须通过显式打破循环帮忙。这可以通过释放所有引用从页面到控件 (如上文所建议) 或通过都释放从控制到可能指向页面 (使用页卸载事件取消订阅所有事件处理程序) 的事件处理程序委托的所有引用。
转载于:https://www.cnblogs.com/Nukepayload2/p/win2d_doc_vb_memleak.html
Win2D 入门教程 VB 中文版 - 防止内存泄漏相关推荐
- Win2D 入门教程 VB 中文版
继续填坑!又一个c#教程变为vb! 这是我翻译的Win2D教程,链接保留了微软原版的. 如果文档有问题,可以在 https://github.com/Nukepayload2/Win2dDocVB发 ...
- 苹果Swift编程语言入门教程【中文版】
Swift代码语言教程:在刚刚过去的WWDC2014大会上,苹果公司新发布了一种编程语言Swift.据悉,Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题,对于广 ...
- snap7使用说明中文版_Python官方入门教程_中文版_3.7.3
张小森:Python官方入门教程/2. 使用 Python 解释器zhuanlan.zhihu.com 张小森:Python官方入门教程_中文版_3. Python 的非正式介绍zhuanlan. ...
- Win2D 官方文章系列翻译 - 避免内存泄漏
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-avoiding-memory-leaks/ 在托管 XAML 应用中使用 Win2D 控件时,必须谨慎处理对 ...
- 苹果Swift语言入门教程【中文版】
目录 1 简介 2 Swift入门 3 简单值 4 控制流 5 函数与闭包 6 对象与类 7 枚举与结构 1 简介 今天凌晨Apple刚刚发布了Swift编程语言,本文从其发布的书籍<The ...
- python数据结构中文版_Python官方入门教程_中文版_5.数据结构
5. 数据结构 本章将详细介绍一些您已经了解的内容,并添加了一些新内容. 5.1. 列表的更多特性 列表数据类型还有很多的方法.这里是列表对象方法的清单: list.append(x) 在列表的末尾添 ...
- java 内存泄漏 工具_Java剖析工具JProfiler入门使用教程:查找内存泄漏的方法
JProfiler的内存视图会话提供了内存使用情况的动态更新视图以及分配点的信息视图.所有的视图都有几个聚集层并且能够显示现有存在的对象和作为垃圾回收的对象.本文主要介绍如何意识到内存泄漏以及查找内存 ...
- Clojure入门教程: Clojure – Functional Programming for the JVM中文版
http://xumingming.sinaapp.com/302/clojure-functional-programming-for-the-jvm-clojure-tutorial/ api:h ...
- UWP开发入门(十六)——常见的内存泄漏的原因
原文:UWP开发入门(十六)--常见的内存泄漏的原因 本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)--用Diagno ...
最新文章
- CentOS7配置防火墙
- 【SSH网上商城项目实战17】购物车基本功能的实现
- 【错误记录】编译 Linux 内核报错 ( /bin/sh: 1: bison: not found )
- laravel 框架的 csrf
- 解决方案需求提升 安防工程细节化事项要了解
- 8750H带的动MATLAB2019吗,[多图]九代i7-9750H笔记本标压处理器与前代8750H性能对比
- .NET混淆器 Dotfuscator如何保护应用程序?控制流了解一下!
- Kubernetes基础组件概述
- 为什么跨境电商独立站将成为几年的焦点?
- 梯度下降法and实战
- 【跨域】springBoot + VUE解决跨域问题几种处理方案
- win10 添加照片查看器
- 2008服务器系统初始密码,2008服务器地址和密码
- 微信原样返回echostr也无法验证通过的原因
- 过滤百度广告+搜索热点+adblock规则快速入门
- 倍福--运动中修改速度
- 抖音电商主播考核绩效直播运营KPI方案
- AI作画的业界天花板被我找到了,AIGC模型揭秘 | 昆仑万维
- Agc012_E Camel and Oases
- visio图形线性阵列