标签: finalizer

在 .net 对象的终结器中调用 glDeleteTextures 的正确方法

我即将围绕 OpenGL 纹理实现一个托管包装类,并且我希望对象终结器调用glDeleteTextures.

因此,调用终结器的线程(GC线程?)必须通过调用绑定到纹理所属的OpenGL渲染上下文wglMakeCurrent

wglMakeCurrent文档明确指出,一个OpenGL渲染上下文不能同时是多个线程的当前渲染上下文。

如果GC可以随时触发,我不能保证发生时没有其他线程正在使用上下文。

glDeleteTextures调用 .net 对象的终结器的正确方法是什么?

编辑

该包装类将用于“按需加载”场景图的复杂系统,并通过WeakReference等等实现缓存策略。因此,“手动处置”不是我想要考虑的选项:我真的希望 GC 能够处理这个问题。

.net opengl multithreading garbage-collection finalizer

5
推荐指数
2
解决办法
1124
查看次数

除非使用weakref,否则在创建第二个对象之前未调用终结器

我在玩 ruby​​ 终结器并注意到一些对我来说很奇怪的行为。我可以将触发代码减少到以下内容:

require "weakref"

class Foo
    def initialize
        ObjectSpace.define_finalizer(self, self.class.finalize)
    end

    def self.finalize
        proc {
            puts "finalizing"
        }
    end
end

Foo.new # does not work
#WeakRef.new(foo) # Using this instead, everything works as expected
sleep 1
ObjectSpace.garbage_collect
puts "... this did not finalize the object"

Foo.new
ObjectSpace.garbage_collect
puts "but this did?"
Run Code Online (Sandbox Code Playgroud)

正如程序所说,在第二次调用 Foo.new 之前没有运行终结器。我尝试在第一次调用垃圾收集器之前添加更多延迟(尽管据我所知,它根本不需要),但这没有任何作用。

奇怪的是,如果我使用注释掉的行 i,第一个终结器会像我期望的那样被调用。第二个在程序退出之前仍然没有被调用。

谁能解释为什么会这样?我正在运行带有 ruby​​ 1.9.3p194(2012-04-20 修订版 35410)[x86_64-linux] 的 Ubuntu 12.10。我尝试阅读弱引用代码,但据我所知,它所做的只是存储对象 object_id 以便稍后检索它。

编辑:我知道在这种情况下手动调用垃圾收集器是没有意义的。我只是想了解这背后的机制。

ruby weak-references finalizer

5
推荐指数
1
解决办法
417
查看次数

Gradle 缺少动态任务

我有一个已宣布的任务:

tasks.getByName('connectedAndroidTest').finalizedBy 'archiveReports'
Run Code Online (Sandbox Code Playgroud)

但是当我尝试构建项目时,它告诉我:

Caused by: org.gradle.api.UnknownTaskException: Task with name 'connectedAndroidTest' not found in project ':TestProject'.
        at org.gradle.api.internal.tasks.DefaultTaskCollection.createNotFoundException(DefaultTaskCollection.java:80)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:229)
        at org.gradle.api.internal.tasks.DefaultTaskCollection.getByName(DefaultTaskCollection.java:31)
        at org.gradle.api.tasks.TaskCollection$getByName.call(Unknown Source)
        at build_6w8zk6ic8wtqwlvwwubix2jc3.run(/path/to/build.gradle:84)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:91)
        ... 58 more
Run Code Online (Sandbox Code Playgroud)

如果我将其更改为其他方式:

tasks.connectedAndroidTest.finalizedBy 'archiveReports'
Run Code Online (Sandbox Code Playgroud)

这个问题非常相似:

Caused by: groovy.lang.MissingPropertyException: Could not get unknown property 'connectedAndroidTest' for task set.
        at org.gradle.internal.metaobject.AbstractDynamicObject.getMissingProperty(AbstractDynamicObject.java:92)
        at org.gradle.internal.metaobject.AbstractDynamicObject.getProperty(AbstractDynamicObject.java:62)
        at org.gradle.api.internal.tasks.DefaultTaskContainer_Decorated.getProperty(Unknown Source)
        at build_6w8zk6ic8wtqwlvwwubix2jc3.run(/path/to/build.gradle:84)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:91)
        ... 58 more
Run Code Online (Sandbox Code Playgroud)

我知道这个任务是由于风格而动态生成的,但是如何向动态任务添加终结器?

finalizer gradle build.gradle android-gradle-plugin gradle-task

5
推荐指数
0
解决办法
832
查看次数

如果结构可以实现 IDisposable,为什么它们不能有析构函数?

我阅读了类似问题的已接受答案,部分答案是:

当结构作为参数传递时,它们是按值传递的:它们被复制。现在你有两个具有相同内部字段的结构,它们都将尝试清理同一个对象。一个会首先发生,因此随后使用另一个的代码将开始神秘地失败......然后它自己的清理将失败

同样的问题不也适用于吗Dispose()?如果结构可以实现IDisposable,那么不允许它们具有终结器的原因是什么?

如果终结器的全部目的是Dispose(false)在程序员忘记调用时进行调用Dispose(),并且结构可以具有IDisposable.Dispose(),那么为什么不允许结构的终结器而允许它们用于引用类型呢?

c# destructor idisposable finalizer

5
推荐指数
1
解决办法
1401
查看次数

在非托管资源上执行 P/Invoke 时何时需要 GC.KeepAlive(this)?

我有一个TestNet本机组件的包装器。本机组件公开了一个通过调用托管回调与托管部分进行通信的阻塞 ,以及一个用于检索对 .NET 包装器的引用并提供上下文的弱函数。它很弱,因为 .NET 包装器旨在隐藏正在向用户处理非托管资源的事实,并且故意不实现该接口:非弱它会根本阻止实例被收集,从而造成内存泄漏。发生的情况是,在发布版本中,只有垃圾收集器会在执行托管回调时收集对 .NET 包装器的引用,甚至在两者之前并且令人惊讶地解除阻塞。我自己理解这个问题,我可以通过在 P/Invoke 调用后发出 a 来解决它,但由于这方面的知识不是很广泛,似乎很多人都做错了。我有几个问题:TestNative::Foo()GCHandleGCHandleIDisposableTestNetTestNative::Foo()TestNet::Foo()GC.KeepAlive(this)

  1. 如果GC.KeepAlive(this)最后一条指令是对非托管资源的 P/Invoke 调用,或者仅在这种特殊情况下需要,即在从本机代码封送托管回调时切换到托管执行上下文,则托管方法中始终需要该指令?问题可能是:我应该GC.KeepAlive(this)到处放吗?这个旧的微软博客(原始链接是404,这里被缓存)似乎是这么建议的!但这将改变游戏规则,基本上这意味着大多数人从未正确执行过 P/Invoke,因为这需要在包装器中检查大多数 P/Invoke 调用。例如,是否有一条规则规定,当执行上下文非托管(本机)时,垃圾收集器(编辑:或更好的终结器)无法为属于当前线程的对象运行?
  2. 我在哪里可以找到适当的文档?我可以找到 CodeAnalysis 策略CA2115指向通常在使用 P/Invoke 访问非托管资源时使用的GC.KeepAlive(this) 策略。一般来说,在处理终结器GC.KeepAlive(this)时似乎很少需要。
  3. 为什么这种情况只发生在发布版本中?它看起来像是一种优化,但在调试构建中根本不需要,隐藏了垃圾收集器的重要行为。

注意:我对收集代表没有问题,这是一个不同的问题,我知道如何正确处理。这里的问题是,当 P/Invoke 调用尚未完成时,会收集持有非托管资源的对象。

它遵循的代码清楚地表明了问题。创建一个 C# 控制台应用程序和一个 C++ Dll1项目并在发布模式下构建它们:

程序.cs

using System;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        static void …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke garbage-collection callback finalizer

5
推荐指数
1
解决办法
1860
查看次数

用于同步的空引用(monitor-enter)

当我关闭互联网连接并从 Firebase 应用注销时,我无法退回我的应用。

还得到下一个错误:

2019-11-05 20:26:19.364 5593-5611/com.mandarine.target_list E/System:
    Uncaught exception thrown by finalizer 2019-11-05 20:26:19.3655593-5611/com.mandarine.target_list E/System:
java.lang.NullPointerException: Null reference used for synchronization (monitor-enter)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.finalize(ConscryptFileDescriptorSocket.java:1053)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:252)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:239)
        at java.lang.Daemons$Daemon.run(Daemons.java:105)
        at java.lang.Thread.run(Thread.java:764)
Run Code Online (Sandbox Code Playgroud)

它仅在我关闭 Internet 时发生。

我也发现了这个:https : //github.com/google/conscrypt/blob/master/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java#L1079

但真的不知道该怎么做必须得到

我也做了/gradlew app:androidDependencies并得到:

> releaseUnitTestRuntimeClasspath - Dependencies for runtime/packaging
> +--- org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.3.50@jar
> +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50@jar
> +--- com.firebaseui:firebase-ui-auth:4.3.1@aar
> +--- androidx.navigation:navigation-ui-ktx:2.0.0@aar
> +--- androidx.navigation:navigation-ui:2.0.0@aar
> +--- com.google.android.material:material:1.0.0@aar
> +--- me.zhanghai.android.materialprogressbar:library:1.4.2@aar
> +--- androidx.appcompat:appcompat:1.0.2@aar
> +--- androidx.constraintlayout:constraintlayout:1.1.3@aar
> +--- …
Run Code Online (Sandbox Code Playgroud)

android garbage-collection finalizer nullpointerexception kotlin

5
推荐指数
1
解决办法
2073
查看次数

最终程序的问题(gfortran 的段错误)

考虑下面的小程序,它重现了我在 mac os 上使用 gfortran gcc 9.2.0 时遇到的分段错误):

module stringmod

   type :: str_t
      character(len=:), allocatable :: s
   contains
      final :: finalize
   end type str_t   

   type :: static_t  
      type(str_t) :: expr(3)
   end type static_t

   type :: dynamic_t  
      type(str_t), allocatable :: expr(:)
   end type dynamic_t

contains

   subroutine finalize ( x )
      type(str_t), intent(in out) :: x

      if (allocated(x%s)) deallocate(x%s)    

   end subroutine finalize

end module stringmod

use stringmod

implicit none

type(static_t ), allocatable :: stat(:)
type(dynamic_t), allocatable :: dyna(:)
integer                      :: i, j, …
Run Code Online (Sandbox Code Playgroud)

fortran finalizer gfortran

5
推荐指数
1
解决办法
399
查看次数

正确实现Finalize和Dispose的方法(当父类实现IDisposable时)

我在我的类中实现了Finalize和Dispose,我在我的父类上实现了IDisposable并覆盖了我的子类中的Dispose(bool)重载.我不确定

  1. 是否使用重复的isDisposed变量(因为它已经存在于基类中)?
  2. 是否在子类中实现终结器?

这两件事都是在这里给出的例子中完成的 -

http://guides.brucejmack.biz/CodeRules/FxCop/Docs/Rules/Usage/DisposeMethodsShouldCallBaseClassDispose.html

虽然此MSDN文章中的示例没有这两个中的任何一个 - http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx

而MSDN中的这个例子并不完整 - http://msdn.microsoft.com/en-us/library/ms182330.aspx

.net c# wpf idisposable finalizer

4
推荐指数
1
解决办法
5411
查看次数

C#:在终结器中,如何确定应用程序是否正在关闭?

我有一个终结器似乎总是在应用程序关闭期间失败.我认为这是因为它持有一些在那时不再有效的本地资源.有没有办法在析构函数/终结器中告诉它是否因应用程序关闭而被调用?

谢谢!

.net c# destructor finalizer application-shutdown

4
推荐指数
1
解决办法
1281
查看次数

具有静态成员的未引用对象的.NET GC

所以我很好奇,GC会 - 尤其是最终化 - 会x在.NET中的实例上发生:

  • x 什么都没有引用
  • x有一个静态DbConnection属性
  • y 是与...相同的类的实例 x
  • y 仍被某事引用

令我感到震惊的是,在这种情况下,x可以通过外部引用声明死亡 - 但是对它执行最终化可能会导致DbConnectiony仍然需要时进行处理并保留对它的引用.

那么,在我描述的场景中,它被x收集了吗?它最终确定了吗?或者,在收集其中任何一个实例之前,所有类型的实例都需要在堆中进行孤立吗?每个实例都会发生最终化吗?

我会这么认为,遵循的一般规则是:永远不要触摸终结器中的静态或其他共享对象?

.net c# garbage-collection finalizer

4
推荐指数
1
解决办法
65
查看次数