简体   繁体   English

内存管理 - C#VS Objective C?

[英]Memory management - C# VS Objective C?

SO I already know about memory management in objective C, and I never had to know about it while programming in .net (C#). 所以我已经了解了目标C中的内存管理,在使用.net(C#)编程时我从来不需要知道它。 But i still have some questions about how everything is done. 但我仍然对如何完成所有事情有一些疑问。

-Why does the code leak in objective c if we allocate an object and not release it? - 如果我们分配一个对象而不释放它,代码是否在目标c中泄漏?

-Why doesn't this leak in C#? - 为什么C#中没有泄漏?

-What are some advantages and disadvantages of automatic-garbage-collecting? - 自动垃圾收集的优点和缺点是什么?

-Why not use autorelease on every allocated object (Objective C)? - 为什么不在每个分配的对象上使用自动释放(目标C)?

-Is it possible to take care of the memory manually (C#)? - 是否可以手动处理内存(C#)? so let's say i instantiate an object, and when I'm done i want to release it, and i don't want to wait for the garbage collector to do it? 所以让我说我实例化一个对象,当我完成后我想释放它,我不想等待垃圾收集器这样做?

  • It leaks in Objective-C because Objective-C doesn't take any action on it. 它在Objective-C中泄漏,因为Objective-C不对其采取任何操作。 It relies on you doing all the work. 它依靠你做所有的工作。 It doesn't leak in C# (more precisely, in .NET) because it employs a garbage collector which cleans up objects that are no longer used. 它不会在C#中泄漏(更确切地说,在.NET中),因为它使用垃圾收集器来清理不再使用的对象。

  • The main advantage of garbage collection is the above: you have far fewer memory leaks. 垃圾收集的主要优点如上:内存泄漏少得多。 (It's still possible to have a memory leak, eg by filling a list indefinitely, but that's harder to do accidentally.) It used to be thought that garbage collection has a disadvantage in that it could slow down the program because it keeps doing the garbage collection in the background and you have little control over it. (它仍然可能有内存泄漏,例如通过无限期填充列表,但是更难以意外地执行。)过去认为垃圾收集有一个缺点,因为它可能会减慢程序因为它一直在做垃圾在后台收集,你几乎无法控制它。 In reality, however, the difference is negligible: there are other background tasks on your computer (eg device drivers) running all the time, the garbage collector doesn't break the camel's back either. 但实际上,差异可以忽略不计:您的计算机上还有其他后台任务(例如设备驱动程序)一直在运行,垃圾收集器也不会破坏骆驼的后退。

  • Auto-deallocation (as it is employed in C++ when a non-pointer variable goes out of scope) is dangerous because it opens the possibility to have a reference to it still in existence even after the object has been disposed. 自动释放(因为它在非指针变量超出范围时在C ++中使用)是危险的,因为即使在处理了对象之后,它也可以使它仍然存在。 If your code then tries to access the object, the process goes kaboom big time. 如果您的代码然后尝试访问该对象,那么该过程将大大增加。

  • Yes, it is possible to tell C# to release memory by invoking the garbage collector directly ( GC.Collect() ). 是的,可以通过直接调用垃圾收集器( GC.Collect() )来告诉C#释放内存。 However, I have yet to see a case where this is at all necessary. 但是,我还没有看到一个必要的情况。 If you actually run out of memory, the garbage collector will already kick in automatically and free as much as it can. 如果实际上内存不足,垃圾收集器将自动启动并尽可能多地释放。

Objective-C isn't a garbage-collected language, so it has no way of knowing that an object won't be used anymore unless you tell it. Objective-C不是垃圾收集语言,因此除非你告诉它,否则它无法知道对象将不再被使用。 That's the purpose of the .NET garbage collector: it checks to see which objects can no longer be used by the program, and- at some point- gets rid of them to free up memory. 这就是.NET垃圾收集器的目的:它检查程序不能再使用哪些对象,并且 - 在某些时候 - 摆脱它们以释放内存。 There are no guarantees as to when, or if, it will ever free any given abandoned object; 无法确定何时或是否可以释放任何已放弃的物体; it's just trying to keep memory usage from going out of control. 它只是试图让内存使用失控。

C# can't release an object without the garbage collector. 没有垃圾收集器,C#无法释放对象。 If you release an object that's still being referenced, your program is going to crash when you try to use that. 如果您释放仍在引用的对象,则在尝试使用该程序时,程序将崩溃。 Which is always the risk of manual memory management, but like all "memory-managed languages", it is trying to prevent you from making exactly that mistake. 这总是存在手动内存管理的风险,但与所有“内存管理语言”一样,它试图阻止您犯下错误。 If you want to explicitly shut down an object's operation, implement the interface IDisposable for that object's type, and use the Dispose() method on that object- essentially a destructor. 如果要显式关闭对象的操作,请为该对象的类型实现接口IDisposable,并对该对象使用Dispose()方法 - 本质上是析构函数。 Be sure you're done with it, of course, and that the object will behave correctly (by throwing exceptions) if something tries to use it after it's been Dispose()d of. 当然,确保你完成它,并且如果某些东西在Dispose()d之后尝试使用它,那么该对象将表现正确(通过抛出异常)。

Objective-C is reference-counted. Objective-C是参考计数。 When an object is out of references, it deletes itself. 当一个对象没有引用时,它会自行删除。 It's not a bad solution to the "is someone still using this object?" 对于“有人还在使用这个对象吗?”这并不是一个糟糕的解决方案。 problem, except for data structures that refer to themselves; 问题,除了引用自己的数据结构; circular data structures will hang around forever unless carefully handled. 除非小心处理,否则循环数据结构将永远存在。 .NET isn't a reference counter, so it will get rid of circular data structures that can't be reached from running code. .NET不是一个引用计数器,因此它将摆脱运行代码无法访问的循环数据结构。

Autorelease is just a "release later", for returning a value that should self-destruct if the code that grabs it doesn't immediately want to hold onto it, as far as I understand. Autorelease只是一个“稍后发布”,用于返回一个应该自毁的值,如果抓住它的代码不会立即想要保留它,据我所知。 (I'm not an Objective-C programmer, though.) It gets around the "who releases this object?" (不过,我不是Objective-C程序员。)它解决了“谁发布这个对象?” problem for calls that return an object, without destroying it before the function is finished. 返回对象的调用的问题,而不是在函数完成之前销毁它。 It's a special use case, though, and it doesn't make sense in most other cases. 但这是一个特殊的用例,在大多数其他情况下它没有意义。

The advantage of automatic garbage collection is that you do not have to explicitly free/release your objects as you said. 自动垃圾收集的优点是你不必像你说的那样明确释放/释放你的对象。 The disadvantage is you cannot be sure when (or even if) any given object instance will be released. 缺点是您无法确定何时(或者即使)将释放任何给定的对象实例。

C# has other mechanisms to release other resources like files, or db connections that have to be released detirminitely. C#还有其他机制可以释放其他资源,如文件,或者必须在deminrminitely发布的数据库连接。 For example, using allows you to make sure that IDispose is called on an object for sure. 例如, using允许您确保在对象上调用IDispose。

Garbage collected systems tend to have more memory in use at any given time than a well tuned manual implementation. 垃圾收集系统在任何给定时间都倾向于使用比调整良好的手动实现更多的内存。 Of course, you do not have memory leaks. 当然,你没有内存泄漏。

The quality and performance of garbage collectors can vary quite a bit which is something you may not have a lot of control over. 垃圾收集器的质量和性能可能会有很大差异,这是您可能无法控制的。 For example, there may be a noticable lag when the GC runs. 例如,GC运行时可能会出现明显的延迟。 In .NET, you can call GC.Collect() to tell the GC that now would be a good time but it may or may not listen. 在.NET中,您可以调用GC.Collect()来告诉GC现在是个好时机,但它可能听也可能不听。

These days Objective-C is also garbage collected on the Mac. 这些天Objective-C也是在Mac上垃圾收集。 On the iPhone it is reference counted though so I assume that is where you are running into the issue. 在iPhone上它是引用计数,所以我认为这是你遇到问题的地方。

On garbage collected systems, you can still run into the issue where a an object hangs onto a reference to an object that you would expect to be garbage collected. 在垃圾收集系统上,您仍然可能遇到一个问题,即一个对象挂在对您希望被垃圾收集的对象的引用上。 The garbage collector will not clean-up this up and so the memory is essentially leaked. 垃圾收集器不会清理它,因此内存基本上是泄漏的。

In reference counted systems, you do not have to keep track of every object that points at your object instances but you do have to specify that you want them released. 在引用计数系统中,您不必跟踪指向对象实例的每个对象,但必须指定要释放它们。

EDIT: I guess I did not say this explicitly - you cannot manually control memory allocation in C#. 编辑:我想我没有明确说明 - 你不能手动控制C#中的内存分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM