标签: finalizer

java:wait(),notify()和synchronized块

我了解到调用Object的wait()方法将释放对象监视器(如果存在).

但我有一些关于notify()通过另一个线程调用此对象的问题:

  1. 如果另一个(第3个)线程同时拥有对象监视器,那么等待线程是否会被唤醒?

  2. 如果第三个线程调用wait()此对象,那么等待线程会被唤醒吗?

  3. 是否可以确定线程是否在等待通知特定对象(java 1.4/java 5)

  4. 如果wait()finalize()方法中调用会发生什么?

java locking finalizer notify wait

8
推荐指数
1
解决办法
6198
查看次数

什么是Finalizer Queue和Control + ThreadMethodEntry?

我有一个WindowsForms应用程序,似乎泄漏内存,所以我使用Redgate的ANTS内存分析器来查看我怀疑的对象,并发现它们只由已经在Finalizer Queue上的对象持有.很棒,究竟什么是Finalizer Queue?你能指出我最好的定义吗?你能分享任何轶事建议吗?

此外,Finalizer Queue上的所有根GC对象都是名为"caller" 的System.Windows.Forms.Control + ThreadMethodEntry对象的实例.我看到它涉及多线程UI交互,但除此之外我不太了解.原谅我明显的懒惰并承认无知,但这些资源都埋藏在供应商的组件中.我正在和供应商讨论这些问题,但我需要一些指导才能让我加快对话速度.你能指点我最有用的ThreadMethodEntry定义吗?任何轶事建议?

另外,我是否应该关注终结器队列中的这些对象?

更新:这篇红门文章很有帮助.

.net memory-leaks finalizer redgate winforms

7
推荐指数
1
解决办法
7811
查看次数

为什么"Finalize方法不应该引用任何其他对象"?

我一直在思考为什么我们建议,我们应该释放里面的finalize管理资源.如果您在http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx上看到代码示例,并搜索字符串"Dispose(bool disposing)在两个不同的场景中执行"并阅读评论,你会明白我的意思.

我能想到的唯一可能性是,它可能与无法预测何时调用终结器的事实有关.有谁知道正确的答案?

谢谢,误导

c# clr garbage-collection dispose finalizer

7
推荐指数
1
解决办法
1064
查看次数

AppDomain.Unload会抛出Finalizer吗?

所以这是迄今为止的故事,我有这个工作者,它使用AppDomain来执行某些任务.该域名设置和拆卸都很昂贵.所以我为工作者创建一个WeakReference对象的每个线程缓存,如下所示:

class Worker
{
    [ThreadStatic]
    static Dictionary<string, WeakReference> _workers;

    public static Worker Fetch( ... ) { you get the idea }

    private AppDomain _domain;
    public Worker(...)
    {
        _domain = AppDomain.Create( ... );
    }

    ~Worker()
    { 
        AppDomain.Unload(_domain);
    }

    // bla bla bla
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,当GC收集时,似乎总是在调用AppDomain.Unload时引发异常:

System.CannotUnloadAppDomainException: Error while unloading appdomain. (Exception from HRESULT: 0x80131015)"
Run Code Online (Sandbox Code Playgroud)

所以我觉得这很奇怪,我知道我在那个领域没有任何"跑步"......这笔交易是什么?我想出了一点挖掘和反复试验:

    ~Worker()
    { 
        new Action<AppDomain>(AppDomain.Unload)
            .BeginInvoke(_domain, null, null);
    }
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

  1. AppDomain.Unload总是会从Finalizer失败吗?为什么?
  2. 我是否会通过上述解决方法体验任何"不受欢迎的"?

c# appdomain finalizer

7
推荐指数
1
解决办法
2688
查看次数

在最终确定最佳实践时关闭连接?

可能重复:
为什么要实现finalize()?

我看到一些带有以下代码的java文件:

public void finalize() {
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 被关闭Connectionfinalize方法最好的做法?
  • 是否足以关闭Connection或需要关闭其他对象,如PreparedStatement

java database-connection finalizer

7
推荐指数
2
解决办法
5364
查看次数

即使使用CriticalFinalizerObject,在未处理的异常之后也不会调用终结器

我有这样的测试代码:

public class A : CriticalFinalizerObject 
{
    ~A()
    {
        File.WriteAllText("c:\\1.txt", "1z1z1");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        throw new Exception();
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,我尝试在不从CriticalFinalizerObject派生A的情况下运行它.在该程序结束后没有调用终结器.这令我感到惊讶,因为我认为这更具确定性,但没关系.然后我读到了关于CriticalFinalizerObject的内容,确保调用它们的终结器.我从它那里得到了A. 你猜怎么着.它仍然没有被执行.我在做什么/理解错误?

(请不要写关于垃圾收集器是非确定性的明显的东西,我知道.事实并非如此,因为程序结束了,我想我可以安全地清理一个很好的未处理的托管异常.)

.net c# finalizer

7
推荐指数
1
解决办法
1143
查看次数

如何编写适当的析构函数和终结符?

我试图弄清楚如何在C++/CLI中正确清理我的对象之后.

我已经阅读或浏览了这两篇文章(,)并查看了标准并查看了其他一些问题,特别是这一个问题.

我有各种各样的信息:

  1. 终结器应该清理非托管资源(因此当对象被垃圾收集时,所有内容都会被清除.
  2. 析构函数应该清理托管资源(删除Foo或Foo.Dispose()?)并调用终结器(根据1)
  3. 既析构函数和终结器可以被多次调用(参见3的8.8.8第26页端)
  4. 如果调用析构函数,则不再调用终结器(根据1)(不是通过CLR,也就是说,您仍然可以自己调用它)
  5. 析构函数将调用基类析构函数(参见第3页,第25页)
  6. 具有终结器的类应始终具有析构函数(可能是为了确定性地清理非托管资源)
  7. 对终结器的调用不会调用基类终结器(3 19.13.2,第131页)

但也有很多混乱,部分是由于这一事实造成的

  1. 终结器在C#中称为析构函数
  2. 析构函数在内部生成Dispose和Finalize方法(不确定Finalize),但Finalize方法不是终结器
  3. 析构函数的语义在C++中是不同的,并且通常具有确定性清理和垃圾收集的复杂性

我想要的答案是一个类的例子,它包含它可能包含的所有不同类型的数据(托管,非托管,托管但是一次性的,你能想到的其他任何东西)和正确编写的析构函数和终结器.

我有两个更具体的问题:

  1. 通过只有一个bool hasBeenCleanedUp成员处理多次被调用的可能性并使析构函数/终结器中的整个代码以此为条件,是否可以接受?
  2. 什么样的数据只能由析构函数清理,但不能在终结器中清理,因为它可能已经被gc清理了?

destructor c++-cli finalizer

7
推荐指数
1
解决办法
3688
查看次数

内存泄漏终结器错误

我一直在研究内存泄漏并使用内存分析器工具来检查它们.因此,作为一种实践,我有以下代码泄漏活动,因为匿名内部类持有对活动的引用.这是代码:

   public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleOne();
  }

  private void exampleOne() {
    new Thread() {
      @Override
      public void run() {
        while (true) {
          SystemClock.sleep(1000);
        }
      }
    }.start();
  }
}
Run Code Online (Sandbox Code Playgroud)

我在这里有上述泄漏的记忆分析仪图像(6次旋转): 6活动的轮换. 在此输入图像描述

很明显,有6个正在运行的线程持有对外部活动的隐式引用,从而防止它被垃圾回收.

现在,请考虑以下代码:

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleTwo();
  }

  private void exampleTwo() {
    new MyThread().start();
  }

  private static class MyThread extends Thread {
    @Override
    public void run() {
      while (true) {
        SystemClock.sleep(1000);
      }
    } …
Run Code Online (Sandbox Code Playgroud)

android memory-leaks finalizer

7
推荐指数
1
解决办法
1036
查看次数

这是否是IDisposable的有效基类

IDisisposable模式实现起来很昂贵.在开始实际处理资源之前,我已经计算了17行代码.

Eric Lippert最近撰写了一篇博客文章,提出了一个有趣的观点:任何时候终结者都会运行,这是一个错误.我觉得这很有道理.如果始终遵循IDisposable模式,则应始终抑制Finalizer.它永远不会有机会跑.如果我们接受终结器运行是一个错误,那么有一个指导方针迫使开发人员从以下抽象类派生并禁止直接实现IDisposable接口.

public abstract class AbstractDisaposableBase: IDisposable
{
    ~AbstractDisaposableBase()
    {
        ReportObjectLeak();
        Dispose(false); 
    }

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

    protected abstract void Dispose(bool disposing);

    [Conditional("DEBUG")]
    private void ReportObjectLeak()
    {
        //Debug.Assert(false, "leaked instance");
        //throw new Exception("leaked instance");
    }
}
Run Code Online (Sandbox Code Playgroud)

好处很明显:

  1. 如下所示,实现dispose变得简单且无错误:

class MyClass1 : DisablableBase { protected override void Dispose(bool disposing) { //dispose both managed and unmamaged resources as though disposing==true } }
Run Code Online (Sandbox Code Playgroud)
  1. 没有处置对象报告

  2. 始终遵循一次性模式

但是,这样的指南有什么问题吗?

一个可能的问题是所有一次性物体都将定义一个终结器.但由于终结器总是受到抑制,因此不应该有任何性能损失.

你的想法是什么?

c# architecture disposable finalizer

7
推荐指数
1
解决办法
359
查看次数

Python 中的正确终结

我有很多实例,每个实例都有一个唯一的临时文件供其使用(将数据从内存保存到磁盘并稍后检索它们)。

我想确保最终所有这些文件都被删除。然而,我想留出空间来对它们的删除进行细粒度的控制。也就是说,如果需要的话,某些文件可以提前删除(例如,它们太大并且不再重要)。

实现这一目标的最佳/推荐方法是什么?

可能对此有想法

  • try-finalizewith语句不是一个选项,因为我们有许多文件,它们的生命周期可能会相互重叠。而且,它几乎不承认更精细控制的选择。

  • 从我读到的内容来看,__del__这也不是一个可行的选择,因为它甚至不能保证它最终会运行(尽管我并不完全清楚什么是“有风险”的情况)。此外(如果仍然如此),__del__运行时库可能不可用。

  • tempfile图书馆似乎很有前途。然而,文件在关闭后就消失了,这绝对是一个遗憾,因为我希望它们被关闭(当它们不执行任何操作时)以限制打开文件的数量。

    • 该库承诺该文件“一旦关闭(包括对象被垃圾收集时的隐式关闭)就会被销毁”。

      他们如何实现隐式关闭?例如,在 C# 中,我会使用(可靠的)终结器,但事实__del__并非如此。

  • atexit似乎是最好的候选者,它可以作为可靠的终结器,而不是__del__实现安全的一次性模式。与对象终结器相比,唯一的问题是它真正在退出时运行,这相当不方便(如果对象有资格更早地被垃圾收集怎么办?)。

    • 在这里,问题仍然存在。库如何实现方法始终运行?(除非在非常意外的情况下很难做任何事情)

在理想情况下,似乎__del__atexit库的组合可能表现最好。也就是说,清理既在 at__del__又在 中注册的方法进行atexit,而禁止重复清理。如果__del__被调用,注册的将被删除。

唯一(但也很关键)的问题是,__del__如果在 处注册了方法,则该方法不会运行atexit,因为对该对象的引用永远存在。

因此,欢迎任何建议、建议、有用的链接等。

python garbage-collection finalizer temporary-files del

7
推荐指数
1
解决办法
6212
查看次数