{"id":362238,"date":"2024-05-21T01:30:48","date_gmt":"2024-05-21T01:30:48","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=362238"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T01:30:48","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=362238","title":{"rendered":"<span>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0432 VS Code<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 Go \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0447\u0451\u0442 \u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c <a href=\"https:\/\/habr.com\/ru\/articles\/497994\/\">escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0435<\/a>: <code>go build -gcflags '-m=3 -l'<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0442\u0447\u0451\u0442 \u0432 VS Code. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u0430\u043a \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0435\u043e\u0440\u0438\u044e (escape-\u0430\u043d\u0430\u043b\u0438\u0437) \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 (\u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435).<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/4c3\/de3\/023\/4c3de3023c7958247f2ed88de43bcc35.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4c3\/de3\/023\/4c3de3023c7958247f2ed88de43bcc35.png\"\/><\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"vizualizaciya-s-ispolzovaniem-gopls\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c gopls<\/h2>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/landontclipp.github.io\/blog\/2023\/07\/15\/analyzing-go-heap-escapes\/#configuring-vscode-for-gc-heap-escape-highlighting\" rel=\"nofollow noopener noreferrer\">Analyzing Go Heap Escapes<\/a>.<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0418\u0434\u0451\u043c \u0432 <code>Manage -> Settings -> User<\/code>, \u0442\u0430\u043c \u0438\u0449\u0435\u043c <code>gopls<\/code>, \u0434\u0430\u043b\u0435\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c <code>Edit in settings.json<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 (\u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043c. <a href=\"https:\/\/github.com\/golang\/vscode-go\/wiki\/settings\" rel=\"nofollow noopener noreferrer\">\u0442\u0443\u0442<\/a>):<\/li>\n<\/ol>\n<p>  <\/p>\n<pre><code class=\"json\">    \"gopls\": {                 ...         \"ui.codelenses\": {             \"gc_details\": true         },         \"ui.diagnostic.annotations\": {             \"escape\": true         },         ...     },<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430 <code>Toggle gc annotation details<\/code>, \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0441\u043a\u043e\u043c\u0443\u044e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/511\/29e\/26b\/51129e26b6d2f5adb3d9beeebe4df7e5.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/511\/29e\/26b\/51129e26b6d2f5adb3d9beeebe4df7e5.png\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0421\u0441\u044b\u043b\u043a\u0430 <code>Toggle gc annotation details<\/code> \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0432 workspace \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043f\u043e\u043a).<\/li>\n<li>\u041c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0443\u0447\u0430\u0438 <code>escape to heap<\/code> \u0438 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 <code>leaking param<\/code>.<\/li>\n<li>\u0421\u0441\u044b\u043b\u043a\u0438 \u0432 \u043e\u043a\u043d\u0435 Problems \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441 \u044d\u0442\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e \u0434\u043b\u044f \u043c\u043e\u0435\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (Windows 11), \u043d\u043e \u044f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043e\u0431\u0445\u043e\u0434\u0430 \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"vizualizaciya-s-ispolzovaniem-tasks\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Tasks<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u043d <a href=\"https:\/\/github.com\/microsoft\/vscode-go\/issues\/1948\" rel=\"nofollow noopener noreferrer\">\u0437\u0434\u0435\u0441\u044c<\/a>:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c <a href=\"https:\/\/github.com\/maxim-ge\/itblog-go-escape\/blob\/main\/escape-bench-tasks.json\" rel=\"nofollow noopener noreferrer\">\u0437\u0430\u0434\u0430\u0447\u0438<\/a> \u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u044c \u0438\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430.<\/li>\n<li><code>F1 -> Tasks: Open User Tasks<\/code>.<\/li>\n<li>\u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0451 \u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u043d\u0435\u0435 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e<\/li>\n<li>\u0414\u043b\u044f Windows \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c <code>Git Bash<\/code> \u043a\u0430\u043a \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e: <code>F1 -> Terminal: Select Default Profile<\/code><\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0447\u0435\u0440\u0435\u0437 <code>F1 -> Tasks: Run Task<\/code>:<\/p>\n<p>  <\/p>\n<ol>\n<li>Go: Escape analysis, leaking + escapes.<\/li>\n<li>Go: Escape analysis, escapes only.<\/li>\n<li>Go: Escape analysis, detailed, for current file and line.<\/li>\n<li>Go: Profile current benchmark (memory).<\/li>\n<li>Go: Profile current benchmark (cpu).<\/li>\n<li>Environment.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041a escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0438 1-3, \u043a \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u2014 4 \u0438 5, \u0437\u0430\u0434\u0430\u0447\u0430 6 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043e\u043a\u043d\u0435 <code>Terminal<\/code> \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 \u043e\u043a\u043d\u0435 <code>Terminal<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0421\u0442\u0440\u043e\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u043e\u043a\u043d\u043e <code>Problems<\/code>, \u0432 \u043a\u043e\u0434\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f &#171;\u043a\u0440\u0430\u0441\u043d\u044b\u0435 \u043c\u0435\u0442\u043a\u0438&#187;.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/b43\/c30\/55b\/b43c3055b8b81fa5199e82215986b26d.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/b43\/c30\/55b\/b43c3055b8b81fa5199e82215986b26d.png\"\/><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u043e\u043a\u043d\u043e <code>Problems<\/code>, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>F1 -> Developer: Reload Window<\/code>. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"escape-to-heap-vs-leaking-param\">&#171;Escape to heap&#187; vs &#171;Leaking param&#187;<\/h2>\n<p>  <\/p>\n<p><strong>Escape to heap<\/strong> \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u0443\u0447\u0435, \u0430 \u043d\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435 <code>doesNotEscape<\/code> \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0435\u043a\u0435, \u0430 <code>escapes<\/code> \u0443\u0431\u0435\u0433\u0430\u0435\u0442 \u0432 \u043a\u0443\u0447\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func Slices() int {     doesNotEscape := make([]byte, 10000)     escapes := make([]byte, 100000)     return len(doesNotEscape) + len(escapes) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0440\u043e\u0433, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u043a\u0443\u0447\u0443, \u0434\u043b\u044f slice \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/github.com\/golang\/go\/blob\/e418258993cc1a11816baf5d9004cea3b029ae7c\/src\/cmd\/compile\/internal\/ir\/cfg.go\" rel=\"nofollow noopener noreferrer\">\u0442\u0430\u043a\u043e\u0432<\/a> (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/github.com\/golang\/go\/blob\/e418258993cc1a11816baf5d9004cea3b029ae7c\/src\/cmd\/compile\/internal\/escape\/utils.go#L216\" rel=\"nofollow noopener noreferrer\">\u0437\u0434\u0435\u0441\u044c<\/a>):<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">    \/\/ MaxImplicitStackVarSize is the maximum size of implicit variables that we will allocate on the stack.     \/\/   p := new(T)          allocating T on the stack     \/\/   p := &amp;T{}            allocating T on the stack     \/\/   s := make([]T, n)    allocating [n]T on the stack     \/\/   s := []byte(\"...\")   allocating [n]byte on the stack     \/\/ Note: the flag smallframes can update this value.     MaxImplicitStackVarSize = int64(64 * 1024)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 <strong>leaking param<\/strong> \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0438\u043d\u0430\u044f. <code>Leaking param<\/code> \u2013 \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u043e\u0439 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 <code>leaking param<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func ReturnSlice(leaking []byte) []byte {     return leaking }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 &#171;\u043f\u043e\u0431\u0435\u0433\u0430 \u0432 \u043a\u0443\u0447\u0443&#187;, \u043e\u043d \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u0432 \u043a\u043e\u0434\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c <code>ReturnSlice<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ `a` escapes to heap because of the ReturnSlice() leaking param func CallReturnSlice() {     a := make([]byte, 8)     fmt.Println(ReturnSlice(a)) }<\/code><\/pre>\n<p>  <\/p>\n<p><code>Leaking param<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u0448\u0438\u0440\u043d\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">ChatGPT \u0434\u0430\u0451\u0442 \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>In Go (Golang), &#171;leaking param&#187; typically refers to scenarios where a parameter passed to a function escapes to the heap, potentially causing memory inefficiencies. This usually happens in the following scenarios:<\/p>\n<p>  <\/p>\n<ol>\n<li>\n<p><strong>Storing a reference to a variable<\/strong>: When a function stores a reference to a parameter in a variable that outlives the function call, the parameter escapes to the heap.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Returning a pointer to a local variable<\/strong>: If a function returns a pointer to a local variable (including parameters), the local variable escapes.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Sending data to channels<\/strong>: If a parameter is sent over a channel and the channel outlives the function, the parameter escapes.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Capturing in a closure<\/strong>: When a parameter is captured by a closure (anonymous function) that outlives the function call, the parameter escapes.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Interface method calls<\/strong>: If a parameter is passed to an interface method, it may escape because the compiler cannot determine the exact implementation at compile time.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Using <code>defer<\/code> or <code>go<\/code> with parameters<\/strong>: Parameters passed to functions called with <code>defer<\/code> or <code>go<\/code> might escape, especially if the deferred function runs after the calling function returns.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Assigning to a global variable<\/strong>: If a parameter is assigned to a global variable, it escapes.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Slicing or appending to a slice<\/strong>: If a function slices or appends to a slice and the result outlives the function, the slice&#8217;s underlying array may escape.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Passing to a function taking an interface<\/strong>: If a parameter is passed to a function that takes an interface type, it might escape due to the uncertainty about the underlying type.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Using reflection<\/strong>: Using reflection on a parameter, especially if modifying it, can cause it to escape.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Large structs<\/strong>: Sometimes, large structs are moved to the heap to avoid the cost of copying them.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Method receivers<\/strong>: If a method is called on a pointer receiver, the receiver may escape if it is modified in the method.<\/p>\n<p>  <\/li>\n<li>\n<p><strong>Passing to <code>fmt<\/code> package functions<\/strong>: Functions like <code>fmt.Printf<\/code> that accept interface{} parameters can cause those parameters to escape.<\/p>\n<p>  <\/li>\n<\/ol>\n<p>  <\/p>\n<p>Understanding these scenarios can help in optimizing Go code for better memory management, as avoiding unnecessary escapes to the heap can lead to more efficient memory usage.<\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 &#171;\u0443\u0442\u0435\u0447\u043a\u0438&#187; \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>SliceLen()<\/code> \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, slice \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0435\u043a\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ `p` does NOT leak func SliceLen(p []byte) int {     return len(p) }  \/\/ `a` is kept on the stack func CallSliceLen(f func([]byte) int) {     a := make([]byte, 8)     \/\/ Result of SliceLen(a) escapes to heap     fmt.Println(SliceLen(a)) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u0432 \u043a\u0443\u0447\u0443 &#171;\u0443\u0431\u0435\u0433\u0430\u0435\u0442&#187; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>SliceLen()<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>int<\/code>. \u042d\u0442\u043e \u0446\u0435\u043d\u0430 \u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0442\u0438\u043f\u0430 interface{}, \u043e \u0447\u0451\u043c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u043b ChatGPT \u0432 \u043f.9.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/maxim-ge\/itblog-go-escape\" rel=\"nofollow noopener noreferrer\">\u0437\u0434\u0435\u0441\u044c<\/a>, \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 <a href=\"https:\/\/github.com\/maxim-ge\/itblog-go-escape\/blob\/main\/escapes.go\" rel=\"nofollow noopener noreferrer\">escapes.go<\/a> \u0438 <a href=\"https:\/\/github.com\/maxim-ge\/itblog-go-escape\/blob\/main\/escapes_test.go\" rel=\"nofollow noopener noreferrer\">escapes_test.go<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"profilirovanie-ustanovka-po-i-konfiguraciya\">\u041f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u041f\u041e \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u0421\u0443\u0445\u0430 \u0442\u0435\u043e\u0440\u0438\u044f, \u043c\u043e\u0439 \u0434\u0440\u0443\u0433, \u043d\u043e \u0434\u0440\u0435\u0432\u043e \u0436\u0438\u0437\u043d\u0438 \u0437\u0435\u043b\u0435\u043d\u0435\u0435\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0442\u0435\u043e\u0440\u0438\u044e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439. \u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u043a\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u0434\u0430\u0447 4 \u0438 5. \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u041f\u041e \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u041f\u041e:<\/strong><\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/graphviz.org\/download\/\" rel=\"nofollow noopener noreferrer\">Graphviz<\/a> \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432:<br \/> \n<ul>\n<li>\u0414\u043b\u044f Windows \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e: <code>choco install graphviz<\/code><\/li>\n<\/ul>\n<\/li>\n<li>\u0423\u0442\u0438\u043b\u0438\u0442\u044b \u0442\u0438\u043f\u0430 <code>xargs<\/code>, <code>sed<\/code>, <code>grep<\/code>. \u041d\u0430 unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u041e\u0421 \u0432\u0441\u0451 \u044d\u0442\u043e \u0435\u0441\u0442\u044c, \u043d\u0430 Windows, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c git, \u0432\u0441\u0451 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0432 <code>C:\\Program Files\\Git\\usr\\bin<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f:<\/strong><\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b <code>cpu.out<\/code>, <code>mem.out<\/code>, <code>*.test<\/code> \u0438 <code>*.test.exe<\/code> \u0440\u044f\u0434\u043e\u043c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438. \u0412\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 git, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <code>.gitignore<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">*.out *.test *.test.exe<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"profilirovanie\">\u041f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0410\u0432\u0442\u043e\u0440 \u0441\u0442\u0430\u0442\u044c\u0438 &#171;Analyzing Go Heap Escapes&#187; \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 &#171;\u043f\u043e\u0434\u043e\u043f\u044b\u0442\u043d\u043e\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u0442 \u0434\u0432\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ `y`: leaking param func YIfLongest(x, y *string) *string {     if len(*y) > len(*x) {         return y     }     \/\/ `s`: escapes to heap     s := \"\"     return &amp;s }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0451 \u0442\u0435\u0441\u0442 \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func Benchmark_YIfLongest(b *testing.B) {     x := \"x\"     y := \"y\"     for i := 0; i &lt; b.N; i++ {         l := YIfLongest(&amp;x, &amp;y)         if l == nil {             b.Fatal(\"l is nil\")         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u0443\u0440\u0441\u043e\u0440 \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 Benchmark_YIfLongest, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0443 <code>F1 -> Go: Profile current benchmark (cpu)<\/code>. \u0414\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u0432\u0435\u0437\u0442\u0438 \u0438 \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u043a\u043d\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c, \u0433\u0434\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c <code>View -> Source<\/code>:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/4f8\/f56\/b4d\/4f8f56b4dd52f9d6863623de712e73e7.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4f8\/f56\/b4d\/4f8f56b4dd52f9d6863623de712e73e7.png\"\/><\/p>\n<p>  <\/p>\n<blockquote><p><strong>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435! \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0439\u0442\u0438 \u0432 \u043e\u043a\u043d\u043e <code>Terminal<\/code> \u0438 \u043d\u0430\u0436\u0430\u0442\u044c <code>Ctrl+C<\/code>.<\/strong> \u042d\u0442\u043e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p><\/blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 YIfLongest \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u043e\u0431\u0449\u0435. \u041a \u0441\u043b\u043e\u0432\u0443, \u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0438\u043a\u0440\u043e\u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0451 \u0442\u0440\u0443\u0434\u043d\u0435\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043a\u043b\u043e\u043d\u0435\u043d \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c &#171;\u043c\u0435\u043b\u043e\u0447\u044c&#187; \u043a\u0430\u043a \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e. \u041f\u043e\u043a\u0430 \u043c\u043e\u0436\u043d\u043e &#171;\u043e\u0431\u043c\u0430\u043d\u0443\u0442\u044c&#187; \u0442\u0430\u043a, \u0445\u043e\u0442\u044f \u0447\u0443\u0432\u0441\u0442\u0432\u0443\u044e, <a href=\"https:\/\/chat.openai.com\/share\/2fe3af17-32d2-4b6a-a3c3-71fc625690b3\" rel=\"nofollow noopener noreferrer\">\u043d\u0435\u0434\u0430\u043b\u0451\u043a \u0442\u043e\u0442 \u0434\u0435\u043d\u044c, \u043a\u043e\u0433\u0434\u0430 \u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 &#171;\u0441\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e&#187;<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func Benchmark_YIfLongest1_array(b *testing.B) {     x := [5]string{\"a\", \"ab\", \"abc\", \"abcd\", \"abcde\"}     y := [5]string{\"a\", \"ab\", \"abc\", \"abcd\", \"abcde\"}      for i := 0; i &lt; b.N; i++ {         l := YIfLongest(&amp;x[i%len(x)], &amp;y[i%len(y)])         if l == nil {             b.Fatal(\"l is nil\")         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Benchmark_YIfLongest1_array \u043f\u043e CPU (<code>F1 -> Tasks: Run Task -> Go: Profile current benchmark (cpu)<\/code>):<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/fdd\/256\/3a0\/fdd2563a020e54c0ad53d7daae400328.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/fdd\/256\/3a0\/fdd2563a020e54c0ad53d7daae400328.png\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u0443 \u0432\u043e\u0442, \u0442\u0435\u043f\u0435\u0440\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u0430. \u0417\u0430\u043f\u0443\u0441\u043a <code>Benchmark_YIfLongest1_array<\/code> \u0438\u0437 IDE \u0434\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">goos: windows goarch: amd64 pkg: escapes cpu: 12th Gen Intel(R) Core(TM) i7-12700 Benchmark_YIfLongest1_array Benchmark_YIfLongest1_array-20 1000000000           0.5286 ns\/op          0 B\/op          0 allocs\/op<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u0431\u0435\u0433\u043e\u0432 \u0432 \u043a\u0443\u0447\u0443 \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0434\u0432\u043e\u0439\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430. \u041f\u043e\u043a\u0430 &#171;\u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u044c \u043a \u043f\u043e\u0431\u0435\u0433\u0443&#187; \u043c\u043e\u0436\u043d\u043e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u043e\u0439 <code>\/\/go:noinline<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/go:noinline func YIfLongest_noinline(x, y *string) *string {     if len(*y) > len(*x) {         return y     }     s := \"\"     return &amp;s }  func Benchmark_YIfLongest_noinline(b *testing.B) {     x := \"x\"     y := \"y\"     for i := 0; i &lt; b.N; i++ {         l := YIfLongest_noinline(&amp;x, &amp;y)         if l == nil {             b.Fatal(\"l is nil\")         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">67038356            16.70 ns\/op       16 B\/op          1 allocs\/op<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438 <code>F1 -> Tasks: Open User Tasks -> Go: Profile current benchmark (memory)<\/code>:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/aad\/31e\/e88\/aad31ee88f4d6f1b5a01f49424898643.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/aad\/31e\/e88\/aad31ee88f4d6f1b5a01f49424898643.png\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u044f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f \u0432 \u0441\u0432\u043e\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 &#171;\u0448\u0438\u0448\u043a\u0438&#187;.<\/p>\n<p>  <\/p>\n<h2 id=\"zamykaniya\">\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ `v` and `closure` escape func ProvideClosure(closureCaller func(func() int) int) int {     var v int     closure := func() int {         v++         return 2     }     return closureCaller(closure) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435 \u0438 \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 &#171;\u0443\u0431\u0435\u0433\u0430\u044e\u0442 \u0432 \u043a\u0443\u0447\u0443&#187;, \u0447\u0442\u043e, \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u041c\u0435\u043d\u0435\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432 \u043a\u0443\u0447\u0443 \u0431\u0443\u0434\u0435\u0442 \u0443\u0431\u0435\u0433\u0430\u0442\u044c \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435, \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func (c *Closure) Do() int {     c.v++     return 2 }  \/\/ c.Do escapes func (c *Closure) ProvideInterfaceMethodAsClosure(closureCaller func(func() int) int) int {     return closureCaller(c.Do) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u043e\u043d\u043e \u0443\u0431\u0435\u0433\u0430\u0435\u0442. \u0412 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043f\u043e\u0434 \u043c\u043e\u0438\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e\u043c \u0431\u044b\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func (ff *fields) Fields(cb func(IField)) {     for _, n := range ff.fieldsOrdered {         cb(ff.Field(n))     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0442\u0430\u043a\u0438\u0435 \u0448\u0442\u0443\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 highload \u043f\u043e\u0442\u043e\u043a\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 &#171;\u0442\u0435\u0447\u044c&#187; \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u043e. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u044d\u0442\u043e \u043d\u0435 \u0437\u0430\u043d\u044f\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0430 &#171;premature optimization is the root of all evil in programming&#187;.<\/p>\n<p>  <\/p>\n<h2 id=\"deserializaciya\">\u0414\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c int64 \u0438\u0437 io.Reader \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0430 \u0441\u0442\u0435\u043a\u0435?<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func ReadInt64UsingBinaryRead(r io.Reader) (int64, error) {     var v int64     err := binary.Read(r, binary.BigEndian, &amp;v)     return v, err }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043b\u0443\u0447\u0438\u0442\u0441\u044f 8 \u0431\u0430\u0439\u0442 \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Benchmark_ReadInt64UsingBinaryRead-20 65526505            16.23 ns\/op        8 B\/op          1 allocs\/op<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043b\u0443\u0447\u0430\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0434\u0435\u0441\u044c:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/36a\/09b\/947\/36a09b947f07594ba021de8ce8fdc5df.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/36a\/09b\/947\/36a09b947f07594ba021de8ce8fdc5df.png\"\/><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0447\u0435\u043c \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 Go 1.20 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>v<\/code> \u0442\u043e\u0436\u0435 \u0443\u0431\u0435\u0433\u0430\u043b\u0430 \u0432 \u043a\u0443\u0447\u0443! \u042d\u0442\u043e\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0444\u0435\u043d\u043e\u043c\u0435\u043d \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u0438\u043a\u0435 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li>go install golang.org\/dl\/go1.20.12@latest<\/li>\n<li>go1.20.12 download<\/li>\n<li>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>go<\/code> \u043d\u0430 <code>go1.20.12<\/code> \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438 &#171;Go: Escape analysis, leaking + escapes&#187; \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443.<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0432 VS Code. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u043b \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u0430\u043a \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0435\u043e\u0440\u0438\u044e (escape-\u0430\u043d\u0430\u043b\u0438\u0437) \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 (\u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435) \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043f\u0430\u0440\u0443 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0433\u0440\u0430\u0431\u043b\u0435\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430. \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u043f\u043e\u0431\u0435\u0433\u0438 \u0432 \u043a\u0443\u0447\u0443, \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/6f7\/f25\/618\/6f7f25618810e6df8faa3219f9307f54.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/6f7\/f25\/618\/6f7f25618810e6df8faa3219f9307f54.png\"\/><\/p>\n<p>  <\/p>\n<h2 id=\"ispolzovannye-materialy\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b<\/h2>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/landontclipp.github.io\/blog\/2023\/07\/15\/analyzing-go-heap-escapes\/#configuring-vscode-for-gc-heap-escape-highlighting\" rel=\"nofollow noopener noreferrer\">Landon&#8217;s Blog, Analyzing Go Heap Escapes<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/microsoft\/vscode-go\/issues\/1948\" rel=\"nofollow noopener noreferrer\">github.com\/microsoft, [proposal] Visualising inline\/escape analysis output<\/a><\/li>\n<li><a href=\"https:\/\/go.microsoft.com\/fwlink\/?LinkId=733558\" rel=\"nofollow noopener noreferrer\">VS Code: Integrate with External Tools via Tasks<\/a><\/li>\n<li><a href=\"https:\/\/code.visualstudio.com\/docs\/editor\/variables-reference\" rel=\"nofollow noopener noreferrer\">VS Code: Variables Reference<\/a><\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/778938\/\"> https:\/\/habr.com\/ru\/articles\/778938\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 Go \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0447\u0451\u0442 \u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c <a href=\"https:\/\/habr.com\/ru\/articles\/497994\/\">escape-\u0430\u043d\u0430\u043b\u0438\u0437\u0435<\/a>: <code>go build -gcflags '-m=3 -l'<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0442\u0447\u0451\u0442 \u0432 VS Code. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u0430\u043a \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0435\u043e\u0440\u0438\u044e (escape-\u0430\u043d\u0430\u043b\u0438\u0437) \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 (\u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435).<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/4c3\/de3\/023\/4c3de3023c7958247f2ed88de43bcc35.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4c3\/de3\/023\/4c3de3023c7958247f2ed88de43bcc35.png\"\/><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-362238","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/362238","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=362238"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/362238\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=362238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=362238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=362238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}