{"id":1065,"date":"2013-07-05T01:00:00","date_gmt":"2013-07-05T00:00:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1065"},"modified":"2015-02-19T20:36:31","modified_gmt":"2015-02-19T20:36:31","slug":"garbage-collection-is-harmful","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1065","title":{"rendered":"Garbage Collection is Harmful"},"content":{"rendered":"<p>I don\u00e2\u20ac\u2122t like garbage collection.<\/p>\n<p>Fundamentally, my problem with languages that have a garbage collected memory model is this: <em>memory is not the only resource<\/em>.<\/p>\n<p>Resource Acquisiation is Initialisation. RAII as it\u00e2\u20ac\u2122s often abbreviated to. RAII and object oriented languages go together beautifully because the language does the heavy lifting with its automatic calling of constructors and, more particularly, destructors.<\/p>\n<p>Garbage collection encourages you to write non-object-oriented code in your fancy object oriented language, and worse, it doesn\u00e2\u20ac\u2122t remove the need for you to manage resources anyway. Garbage collection only works on memory. When the resource isn\u00e2\u20ac\u2122t memory, like, mutex\u00e2\u20ac\u2122s, texture buffers, file handles, network sockets, you <em>still<\/em> have to manage the resource yourself, and you also end up needing a pseudo-destructor.<\/p>\n<pre class=\"sourceCode java\"><code class=\"sourceCode java\"><span class=\"kw\">class<\/span> FileObject {\n    <span class=\"kw\">public<\/span> FileObject( name ) {\n        <span class=\"fu\">open<\/span>(name);\n    }\n\n    <span class=\"co\">\/\/ There is no destructor in Java, finalize() is closest<\/span>\n    <span class=\"fu\">@Override<\/span>\n    <span class=\"kw\">protected<\/span> <span class=\"fu\">finalize<\/span>() <span class=\"kw\">throws<\/span> Throwable {\n        <span class=\"kw\">try<\/span> {\n            <span class=\"fu\">close<\/span>();\n        } <span class=\"kw\">finally<\/span> {\n            <span class=\"kw\">super<\/span>.<span class=\"fu\">finalize<\/span>();\n        }\n    }\n\n    <span class=\"kw\">public<\/span> <span class=\"dt\">void<\/span> <span class=\"fu\">close<\/span>();\n    <span class=\"kw\">public<\/span> <span class=\"dt\">void<\/span> <span class=\"fu\">open<\/span>();\n    <span class=\"co\">\/\/ ... read, write, the rest ...<\/span>\n};\n\n<span class=\"dt\">void<\/span> <span class=\"fu\">someFunction<\/span>() {\n    <span class=\"co\">\/\/ Let&#39;s say uniquefile.txt can&#39;t be opened more than once at any<\/span>\n    <span class=\"co\">\/\/ one time<\/span>\n    FileObject openOnce = <span class=\"kw\">new<\/span> FileObject(<span class=\"st\">&quot;uniquefile.txt&quot;<\/span>);\n    <span class=\"co\">\/\/ use<\/span>\n    openOnce.<span class=\"fu\">read<\/span>();\n\n    <span class=\"co\">\/\/ ... tidy up ...<\/span>\n}<\/code><\/pre>\n<p>So, what do we do for tidying up? \u00e2\u20ac\u0153Garbage collection\u00e2\u20ac\u009d you might cry, \u00e2\u20ac\u0153<code>someFunction()<\/code> will finish, <code>openOnce<\/code> will go out of scope, making its reference count go to zero, the garbage collector will call the destructor, which will call <code>close()<\/code>\u00e2\u20ac\u009d. You wish that\u00e2\u20ac\u2122s what happens. It\u00e2\u20ac\u2122s not though.<\/p>\n<p>The problem is this: the garbage collector doesn\u00e2\u20ac\u2122t run in-thread, when <code>openOnce<\/code> has its reference count reduced to zero, that\u00e2\u20ac\u2122s <em>all<\/em> that happens. Or rather, all that is guaranteed to happen. In fact, it\u00e2\u20ac\u2122s identical to simply calling <code>openOnce = null;<\/code>. This is about as close as Java has to a <code>delete<\/code>; but the destructor <em>isn\u00e2\u20ac\u2122t<\/em> called instantly.<\/p>\n<p>The garbage collector thread will eventually get around to destructing the object, and the file will be closed. In the meantime, if someone else opens \u00e2\u20ac\u0153<code>uniquefile.txt<\/code>\u00e2\u20ac\u009d, we will have broken our \u00e2\u20ac\u0153only one handle at a time\u00e2\u20ac\u009d rule for this resource. We\u00e2\u20ac\u2122re forced then to use our pseudo-constructor, in this case <code>close()<\/code>.<\/p>\n<pre class=\"sourceCode java\"><code class=\"sourceCode java\"><span class=\"dt\">void<\/span> <span class=\"fu\">someFunction<\/span>() {\n    <span class=\"co\">\/\/ Let&#39;s say uniquefile.txt can&#39;t be opened more than once at any<\/span>\n    <span class=\"co\">\/\/ one time<\/span>\n    FileObject openOnce = <span class=\"kw\">new<\/span> FileObject(<span class=\"st\">&quot;uniquefile.txt&quot;<\/span>);\n    <span class=\"co\">\/\/ use<\/span>\n    openOnce.<span class=\"fu\">read<\/span>();\n\n    openOnce.<span class=\"fu\">close<\/span>();\n}<\/code><\/pre>\n<p>For me then, the question is, why bother with garbage collection?. In all but the simplest of resources (memory), we\u00e2\u20ac\u2122re going to have to call a destructor anyway. (Python has exactly the same <a href=\"http:\/\/blog.lerner.co.il\/dont-use-python-close-files-answer-depends\/\">problems<\/a> because the destructor is a bit hazy, and has been forced to introduce more complexity with its \u00e2\u20ac\u02dc<code>with<\/code>\u00e2\u20ac\u2122 keyword for creating \u00e2\u20ac\u0153contexts\u00e2\u20ac\u009d).<\/p>\n<p>This ties in quite closely with my <a href=\"?p=1104\">earlier article<\/a>, where I covered the principle that a properly written resource-managing object with constructor and destructor will, effectively, automatically garbage collect. There\u00e2\u20ac\u2122s little evidence to suggest that garbage collection is, these days, any kind of massive resource drain. Perversely though, it means you have to care <em>more<\/em> about the lifetime of your non-memory resources than you would in a non-GC language.<\/p>\n<p>It\u00e2\u20ac\u2122s particularly obvious when you see the hoops Python is slowly adding that get jumped through to deal with all the problems that GC creates. The following \u00e2\u20ac\u0153special\u00e2\u20ac\u009d members of objects exist all to avoid the supposed complexity of construction\/destruction.<\/p>\n<ul>\n<li><code>__new__()<\/code><\/li>\n<li><code>__init__()<\/code><\/li>\n<li><code>__enter__()<\/code><\/li>\n<li><code>__del__()<\/code><\/li>\n<li><code>__exit__()<\/code><\/li>\n<\/ul>\n<p>But C++ is the complicated one \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I don\u00e2\u20ac\u2122t like garbage collection. Fundamentally, my problem with languages that have a garbage collected memory model is this: memory is not the only resource. Resource Acquisiation is Initialisation. RAII as it\u00e2\u20ac\u2122s often abbreviated to. RAII and object oriented languages go together beautifully because the language does the heavy lifting with its automatic calling of\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=1065\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[65,78,79,6],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1065"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1065"}],"version-history":[{"count":9,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1065\/revisions"}],"predecessor-version":[{"id":1307,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1065\/revisions\/1307"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}