﻿
{"id":10404,"date":"2019-02-17T19:31:40","date_gmt":"2019-02-17T19:31:40","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=10404"},"modified":"2019-02-17T19:31:40","modified_gmt":"2019-02-17T19:31:40","slug":"angular-subscribe-durumlarinda-memory-leaks-yonetimi-ile-bellek-optimizasyonu","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/angular-subscribe-durumlarinda-memory-leaks-yonetimi-ile-bellek-optimizasyonu\/","title":{"rendered":"Angular &#8211; Subscribe Durumlar\u0131nda Memory Leaks Y\u00f6netimi \u0130le Bellek Optimizasyonu"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Angular uygulamalar\u0131nda &#8220;subscribe&#8221; fonksiyonu neticesinde ihtiyaca d\u00f6n\u00fck veri ak\u0131\u015f\u0131n\u0131 asenkron olarak takip edebildi\u011fimiz yap\u0131lar\u0131m\u0131z mevcuttur. Bunlar; k\u00e2h ActivatedRoute nesnesi ile yap\u0131lan route \u00fczerinde parametreden de\u011fer okuma ama\u00e7l\u0131 takip iken k\u00e2h herhangi bir adrese istek g\u00f6nderen HttpClient nesnesinin herhangi bir http fonksiyonu neticesinde result de\u011ferini elde etmek i\u00e7in yap\u0131lan takiptir. Bunlara benzer yap\u0131lanmalarda &#8220;subscribe&#8221; fonksiyonu ile abone olunmakta ve veriler bu abonelik s\u00fcresince dinlenmekte, neticede gelen veri elde edilmektedir. Bu i\u00e7eri\u011fimizde ise pratikte &#8220;unsubscribe&#8221; fonksiyonu ile bu abonelikleri sonland\u0131rmay\u0131 inceleyecek, teorik olarak <em><strong>neden sonland\u0131rmal\u0131y\u0131z<\/strong><\/em> sorusuna cevap arayaca\u011f\u0131z.<\/p>\n<p>\u0130lk olarak <strong><em>component yap\u0131lanmas\u0131 nas\u0131l?<\/em><\/strong> sorusunu de\u011ferlendirerek i\u015fe ba\u015flayal\u0131m. Angular&#8217;da; herhangi bir x componenti, \u00fcretildikten sonra kullan\u0131m sonunda yok edilebilmekte ve ihtiyaca d\u00f6n\u00fck tekrar \u00fcretilebilmektedir. Lakin bu s\u00fcre\u00e7te \u00f6nceden \u00fcretilen instance yok olsa dahi mevcut abonelikler muhafaza edilmekte, temizlenmemektedir. Dolay\u0131s\u0131yla componentler yeniden yarat\u0131ld\u0131k\u00e7a daha fazla abonelik olu\u015fturulmakta ve bu i\u015flemler bir noktadan sonra bellekte l\u00fczumsuz maliyete sebep olmaktad\u0131r. \u0130\u015fte bizler bu tarz uygulamayla ilgili t\u00fcm i\u015flemler bitti\u011fi halde bellekte yer i\u015fgal eden durumlara <em><strong>memory leaks<\/strong><\/em> ismini vermekteyiz.<\/p>\n<h3>Memory Leaks<\/h3>\n<p>Yukar\u0131da da a\u00e7\u0131klamaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z memory leaks durumunu biraz daha a\u00e7arsak e\u011fer; i\u015fletim sistemi taraf\u0131ndan uygulamaya ayr\u0131lan haf\u0131zay\u0131, uygulaman\u0131n i\u015flevsel \u00f6zelli\u011fi sona erince geri vermeyi ihmal etmesi durumudur diyebiliriz. Memory leaks&#8217;i farketmek bir miktar zaman, mevcut duruma m\u00fcdahalede bulunup bu durumu gidermek daha fazla zaman alabilir. C# vs gibi dillerde bildi\u011fimiz gereksiz bilgi toplay\u0131c\u0131s\u0131(garbage collection) bir nebze bu duruma kar\u015f\u0131 mukavemet g\u00f6stermekte lakin ba\u015f edemedi\u011fi durumlarda uygulaman\u0131n yedi\u011fi haf\u0131zan\u0131n pa\u00e7alardan akt\u0131\u011f\u0131 bilinmektedir.<\/p>\n<p>\u0130\u015fte Angular uygulamalar\u0131nda <em>memory leaks<\/em> konseptini engellemek i\u00e7in i\u015flerimiz bittikten sonra t\u00fcm aboneliklerden \u00e7\u0131k\u0131lmas\u0131 gerekmektedir. O halde <strong><em>ne zaman abonelikten \u00e7\u0131kmak zorunday\u0131z?<\/em><\/strong> sorusuna kar\u015f\u0131l\u0131k a\u00e7\u0131k cevap &#8220;ihtiyac\u0131m\u0131z olmad\u0131\u011f\u0131 zaman&#8221; demek olduk\u00e7a do\u011fru ve net bir cevap olacakt\u0131r. Burada ihtiyac\u0131m\u0131z olmad\u0131\u011f\u0131 zamandan kast\u0131m\u0131z aboneli\u011fi sonland\u0131raca\u011f\u0131m\u0131z zaman\u0131 opsiyonel hale getirmektedir. Bu durum bir anl\u0131k \u00f6fke yahut dikkatsizlikten \u00e7ok erkenden abonelikten \u00e7\u0131kma gibi bir riski getirmektedir. O halde aboneliklerden \u00e7\u0131k\u0131\u015f yapmak i\u00e7in bizlere \u00e7ok daha g\u00fcvenli, basit ve d\u00fcnyaca \u00f6nerilen y\u00f6ntem olan &#8220;OnDestroy&#8221; interface&#8217;inin eleman\u0131 &#8220;ngOnDestroy&#8221; metodu yeti\u015fmektedir. Component imha edilirken tetiklenen &#8220;ngOnDestroy&#8221; fonksiyonu, componente ait olan t\u00fcm abonelikleri sonland\u0131rma g\u00f6revini \u00fcstlenerek bu \u015fekilde s\u00fcre\u00e7teki bellek y\u00f6netimine maksimum katk\u0131y\u0131 sa\u011flayabilir.<\/p>\n<h4>unsubscribe Fonksiyonunun Kullan\u0131m\u0131<\/h4>\n<p>Component i\u00e7erisinde aboneli\u011fi &#8220;Subscription&#8221; tipinden bir de\u011fi\u015fken ile refere edebilir\/tutabilir ve a\u015fa\u011f\u0131daki gibi &#8220;ngOnDestroy&#8221; fonksiyonu ile abonelikleri koparabilirsiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, OnInit, OnDestroy } from '@angular\/core';\r\nimport { HttpClient } from '@angular\/common\/http';\r\nimport { Subscription } from 'rxjs';\r\n\r\n@Component({\r\n  selector: 'app-employees',\r\n  templateUrl: '.\/employees.component.html',\r\n  styleUrls: &#x5B;'.\/employees.component.css']\r\n})\r\nexport class EmployeesComponent implements OnInit, OnDestroy {\r\n  constructor(private httpClient: HttpClient) { }\r\n  employees;\r\n  getObservable: Subscription;\r\n\r\n  ngOnInit() {\r\n    this.getObservable = this.httpClient.get(&quot;https:\/\/localhost:5001\/api\/example&quot;).subscribe(data =&gt; this.employees = data);\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.getObservable.unsubscribe();\r\n  }\r\n}\r\n<\/pre>\n<p>Birden fazla aboneli\u011fin olmas\u0131 durumunda ilgili abonelikleri tek tek de\u011fi\u015fkende refere edip aboneliklerini sonland\u0131rabilece\u011finiz gibi a\u015fa\u011f\u0131da oldu\u011fu gibi hepsini tek bir &#8220;Subscription&#8221; i\u00e7erisinde toplay\u0131p toplu \u015fekilde de aboneliklerini koparabilirsiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, OnInit, OnDestroy } from '@angular\/core';\r\nimport { HttpClient } from '@angular\/common\/http';\r\nimport { Subscription } from 'rxjs';\r\n\r\n@Component({\r\n  selector: 'app-employees',\r\n  templateUrl: '.\/employees.component.html',\r\n  styleUrls: &#x5B;'.\/employees.component.css']\r\n})\r\nexport class EmployeesComponent implements OnInit, OnDestroy {\r\n  constructor(private httpClient: HttpClient) { }\r\n  employees;\r\n  getObservable: Subscription;\r\n\r\n  ngOnInit() {\r\n    this.getObservable = this.httpClient.get(&quot;https:\/\/localhost:5001\/api\/example&quot;).subscribe(data =&gt; this.employees = data);\r\n    this.getObservable.add(this.httpClient.post(&quot;https:\/\/localhost:5001\/api\/example&quot;, {}).subscribe(data =&gt; { }));\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.getObservable.unsubscribe();\r\n  }\r\n}\r\n<\/pre>\n<h4>takeUntil RxJS Operat\u00f6r\u00fcn\u00fcn Kullan\u0131m\u0131<\/h4>\n<p>Her ne kadar unsubscribe fonksiyonu abonelik iptalini a\u00e7\u0131k\u00e7a ger\u00e7ekle\u015ftiriyor olsada ayn\u0131 i\u015flemi yapman\u0131n daha da iyi bir yolu olan &#8220;takeUntil&#8221; RxJS operat\u00f6r\u00fc mevcuttur. Keza &#8220;takeUntil&#8221; operat\u00f6r\u00fc unsubscribe&#8217;a nazaran daha \u00e7ok \u00f6nerilen bir yakla\u015f\u0131md\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, OnInit, OnDestroy } from '@angular\/core';\r\nimport { HttpClient } from '@angular\/common\/http';\r\nimport { Subscription, Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs\/operators';\r\n\r\n@Component({\r\n  selector: 'app-employees',\r\n  templateUrl: '.\/employees.component.html',\r\n  styleUrls: &#x5B;'.\/employees.component.css']\r\n})\r\nexport class EmployeesComponent implements OnInit, OnDestroy {\r\n  constructor(private httpClient: HttpClient) { }\r\n  employees;\r\n  private ngUnsubscribe = new Subject();\r\n\r\n  ngOnInit() {\r\n    this.httpClient.get(&quot;https:\/\/localhost:5001\/api\/example&quot;).pipe(takeUntil(this.ngUnsubscribe)).subscribe(data =&gt; this.employees = data);\r\n    this.httpClient.post(&quot;https:\/\/localhost:5001\/api\/example&quot;, {}).pipe(takeUntil(this.ngUnsubscribe)).subscribe(data =&gt; { });\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.ngUnsubscribe.next();\r\n    this.ngUnsubscribe.complete();\r\n  }\r\n}\r\n<\/pre>\n<p>Sonu\u00e7 olarak; hangi platformda olursak olal\u0131m, hangi mimari yahut \u00e7ekirde\u011fi kullan\u0131rsak kullanal\u0131m bellek y\u00f6netiminde derin bo\u015fluk olu\u015fturan &#8220;Memory Leaks&#8221; durumunu g\u00f6z \u00f6n\u00fcne almal\u0131 ve uygulaman\u0131n i\u015flevi bitti\u011fi zaman uygulamaya ayr\u0131lm\u0131\u015f olan t\u00fcm alanlardan \u00e7ekilmeli, varsa veri ak\u0131\u015flar\u0131n\u0131 veya abonelikleri sonland\u0131rmal\u0131y\u0131z. Dolay\u0131s\u0131yla bu mant\u0131kla Angular uygulamalar\u0131nda da ilgili duruma dikat etmeli ve t\u00fcm subscribe durumlar\u0131n\u0131 i\u015flevi bitti\u011fi zaman sonland\u0131rmal\u0131y\u0131z.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<\/p>\n<p>\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Angular uygulamalar\u0131nda &#8220;subscribe&#8221; fonksiyonu neticesinde ihtiyaca d\u00f6n\u00fck veri ak\u0131\u015f\u0131n\u0131 asenkron olarak takip edebildi\u011fimiz yap\u0131lar\u0131m\u0131z mevcuttur. Bunlar; k\u00e2h ActivatedRoute nesnesi ile yap\u0131lan route \u00fczerinde parametreden de\u011fer okuma ama\u00e7l\u0131 takip iken k\u00e2h herhangi bir adrese&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":7400,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2420,2144,2415,2599,2756],"tags":[2764,2765,2766,2767],"class_list":["post-10404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-angular-4","category-angular-5","category-angular-6","category-angular-7","tag-memory-leaks","tag-takeuntil","tag-takeuntil-rxjs","tag-takeuntil-rxjs-operatoru"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=10404"}],"version-history":[{"count":27,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10404\/revisions"}],"predecessor-version":[{"id":10431,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10404\/revisions\/10431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/7400"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=10404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=10404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=10404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}