面试官问我
如何实现类Foo,您可以在其中计算该类的实例.有更多的线程正在创建该类Foo的实例.
我用以下代码回复了这个问题
public class Foo {
private static int count = 0;
public Foo() {
incrementCount();
}
public void incrementCount() {
synchronize (Foo.class) {
count++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
她再次问我这个问题
如果线程结束,计数器应该减少,你怎么能这样做?
我没有回答这个问题.
我知道finalize()方法,但它取决于Garbage collector调用此方法时,即使我们覆盖finalize().
我还没有解决方案,你能解释一下吗?
假设我有一些asm.js代码,可能是由emscripten创建的.假设它有一些相当大的堆分配结构,它由asm.js函数返回,作为一个指针,由一些JavaScript库拾取,包装在一个漂亮的JavaScript对象中.好到目前为止.
但是,如果该对象超出范围并被垃圾收集,会发生什么.现在,asm.js代码无法知道这一点,因此结构的内存将保持分配状态,从而导致内存泄漏.
有没有办法从JavaScript中向JavaScript对象添加终结器?
这样的终结器可用于释放asm.js中的内存,从而避免内存泄漏.到目前为止,我找不到一个记录在案的便携式方法来实现这一点,但也许我一直在寻找错误的地方.
从?reg.finalizerR中的文档:
除其他外,它提供了一种方法来编写代码,以便在R会话结束时运行而无需进行操作
.Last.为了在包中使用,通常最好在命名空间中的对象上设置终结器:然后在会话结束时调用终结器,或者在会话期间完成命名空间后不久调用它.
似乎我可以reg.finalizer()在R会话结束时使用运行某些代码,但它对我不起作用.我在https://github.com/yihui/finalizer-test准备了一个最小的包,它基本上包含以下代码:
e = new.env()
reg.finalizer(e, function(e) {
message('Bye!')
}, onexit = TRUE)
Run Code Online (Sandbox Code Playgroud)
如果我只是在交互式R会话中运行上面的代码并退出会话,我可以看到该消息Bye!,但是如果我安装上面的包(你可以使用devtools::install_github('yihui/finalizer-test')),在R会话中加载它,并退出R会话,我看不到消息.我想知道为什么在这种情况下不执行终结器.
FWIW,当我安装软件包时,我可以看到以下消息Bye!:
$ R CMD INSTALL .
* installing to library ‘/Users/yihui/R’
* installing *source* package ‘finalizer’ ...
** R
** preparing package for lazy loading
No man pages found in package ‘finalizer’
** help
*** installing help indices
Bye!
** building package indices
** testing if installed package can be …Run Code Online (Sandbox Code Playgroud) 我知道你的设计是无法控制物体被摧毁时发生的事情.我也知道将一些类方法定义为终结器.
然而,C++的RAII的ruby习惯用法(资源在构造函数中初始化,在析构函数中关闭)?即使发生错误或异常,人们如何管理对象内部使用的资源?
使用确保工作:
f = File.open("testfile")
begin
# .. process
rescue
# .. handle error
ensure
f.close unless f.nil?
end
Run Code Online (Sandbox Code Playgroud)
但是每次需要调用open方法时,班级用户必须记住做整个begin-rescue-ensure chacha.
例如,我将有以下课程:
class SomeResource
def initialize(connection_string)
@resource_handle = ...some mojo here...
end
def do_something()
begin
@resource_handle.do_that()
...
rescue
...
ensure
end
def close
@resource_handle.close
end
end
Run Code Online (Sandbox Code Playgroud)
如果异常是由某个其他类引起并且脚本退出,则不会关闭resource_handle.
或者更多的问题我还在做这个C++ - 比如?
当我在C#中阅读一些关于内存管理的文章时,我对Finalizer方法感到困惑.
有许多与之相关的复杂规则.例如,没有人知道终结器何时被调用,即使ctor中的代码抛出,他们也会调用,CLR不保证在程序关闭时调用所有终结器等.
对于什么终结器可以在现实生活中使用?
我发现的唯一一个例子是程序在GC启动时发出蜂鸣声.
您是否在代码中使用了Finalizer并且可能有一些好样本?
UPD:
当开发人员想要确保某些类始终通过IDisposable正确处理时,可以使用终结器.(链接 ;感谢Steve Townsend)
终结器总是被.net框架调用,因此序列可能失控; 即使构造函数失败,仍然可以触发析构函数.
当这样的终结者例外来自第三方库时,这可能带来麻烦:我找不到处理它们的方法!
例如,在下面的代码中,尽管A类的构造函数总是抛出异常而失败,但是A的终结符将由.net框架触发,同时~B()被调用为A具有B类型的属性.
class Program // my code
{
static void Main(string[] args)
{
A objA;
try
{
objA = new A();
}
catch (Exception)
{
}
; // when A() throws an exception, objA is null
GC.Collect(); // however, this can force ~A() and ~B() to be called.
Console.ReadLine();
}
}
public class A // 3rd-party code
{
public B objB;
public A()
{
objB = new B(); // this will lead ~B() to be called.
throw new …Run Code Online (Sandbox Code Playgroud) GC.SuppressFinalize是一个可终结的对象与普通的不可终结对象相同吗?下面的代码似乎证明它们在.NET 2和4上都有不同的对待:
class Class1 {
public Class1()
{
GC.SuppressFinalize(this);
}
//~Class1() { }
}
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i=0; i<100000000; i++)
{
new Class1();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
Run Code Online (Sandbox Code Playgroud)
添加终结器但不更改任何其他内容会导致代码花费更长的时间(12601 ms与889 ms相比).
我认为SuppressFinalize在对象头中设置了一点,使GC将对象视为与非终结对象相同,但似乎并非如此.发生什么了?调用GC.SuppressFinalize的非终结对象和可终结对象之间有什么不同?
class Program : CriticalFinalizerObject
{
static void Main(string[] args)
{
Program p = new Program();
TextWriterTraceListener listener = new TextWriterTraceListener(@"C:\trace.txt");
Trace.Listeners.Clear(); // Remove default trace listener
Trace.Listeners.Add(listener);
Trace.WriteLine("First Trace"); // Generate some trace messages
Trace.WriteLine("Perhaps last Trace.");
}
~Program()
{
Trace.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到文件大小= 0
finilizer 应该执行因为我来自CriticalFinalizerObject
我不想在Finalizer中使用Trace.Close().
@eric利珀特后答复:香港专业教育学院重新编辑的代码,试图把它匹配:约束的执行区域 (但仍然没有成功)
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
class Program : CriticalFinalizerObject
{
static void Main(string[] args)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
catch (Exception e)
{
}
finally
{
Program …Run Code Online (Sandbox Code Playgroud) 我有一个带有一些对象(类型BaseTexture)的应用程序,destroy当它们不再使用时应该调用一个显式函数.否则他们可能会泄漏一些记忆.这应该在它们被垃圾收集之前完成(显然只能在那时完成),但并不总是这样.
在Java中,我会检测并使用它来记录它finalize,但Javascript中不存在这样的事情.
我可以在Chrome(或其他浏览器)中检测到这一点吗?我不关心它是否有错误,需要标志,只能记录一条简单的消息等,只要它在开发过程中有效.BaseTexture已经销毁的事实可以从其source财产中获取.
Object.finalize() 在Java 9中已弃用,我想我理解其中的原因,但我很难看到如何替换它.
我有一个名为Configuration的实用程序类,它实际上有一个实例,它拥有应用程序中的所有内容,并持续应用程序的持续时间.它提供的服务之一是记录:在第一次请求记录消息时,创建记录器(由于各种遗留原因,它是我自己的记录器而不是标准记录器),并在Configuration对象的字段中保存引用,并且在应用程序终止时,无论是正常还是异常,我想释放记录器所拥有的任何资源(这是一个黑盒子,因为我的库的用户可以提供他们自己的实现).
目前,这是通过Configuration.finalize()调用方法实现的logger.close().
我应该做什么呢?