<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>담쟁이</title>
    <link>https://imygnam.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 30 Jun 2026 21:47:08 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>imygnam</managingEditor>
    <image>
      <title>담쟁이</title>
      <url>https://tistory1.daumcdn.net/tistory/3510819/attach/cec662d6fed047c6b7a5197513756c14</url>
      <link>https://imygnam.tistory.com</link>
    </image>
    <item>
      <title>[AWS] non www 을 www 으로 redirect 하기 ( Netlify )</title>
      <link>https://imygnam.tistory.com/131</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. AWS Route53으로 netlify 에 redirect 하기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. non www 을 www으로 redirect 하기.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS Route53으로 netlify 에 redirect 하기.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.lolduo.net&quot;&gt;www.lolduo.net&lt;/a&gt; 을 netlify 에 배포한 &lt;a href=&quot;https://lolduo.netlify.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://lolduo.netlify.app/&lt;/a&gt; 으로 redirect 하기 위해서 CNAME 으로 Route53에서 redirect 해주었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2424&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CuoBs/btsFBNe9UJ7/7x5JsycFgMu6epgR8FpQwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CuoBs/btsFBNe9UJ7/7x5JsycFgMu6epgR8FpQwK/img.png&quot; data-alt=&quot;AWS Route53 에서 www.lolduo.net 내역&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CuoBs/btsFBNe9UJ7/7x5JsycFgMu6epgR8FpQwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCuoBs%2FbtsFBNe9UJ7%2F7x5JsycFgMu6epgR8FpQwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2424&quot; height=&quot;84&quot; data-origin-width=&quot;2424&quot; data-origin-height=&quot;84&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS Route53 에서 www.lolduo.net 내역&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;non www 을 www으로 redirect 하기.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;똑같이 CNAME으로 redirect 하면 되지 않을까 생각하였지만 아래와 같은 에러가 발생합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709723221902&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; 잘못된 요청입니다.
(InvalidChangeBatch 400: RRSet of type CNAME with DNS name lolduo.net. is not permitted at apex in zone lolduo.net.)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단순히 &lt;a href=&quot;http://lolduo.net&quot;&gt;lolduo.net&lt;/a&gt; 만 &lt;a href=&quot;http://www.lolduo.net으로&quot;&gt;www.lolduo.net으로&lt;/a&gt; 변경할 것이라면 S3의 정적 웹 호스팅을 사용하면 편합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 모든 경로를 포함해서 리다이렉트가 필요했습니다. 예를 들어 &lt;a href=&quot;http://lolduo.net/banpick&quot;&gt;lolduo.net/banpick&lt;/a&gt; 을 &lt;a href=&quot;http://www.lolduo.net/banpick&quot;&gt;www.lolduo.net/banpick&amp;nbsp;&lt;/a&gt;&amp;nbsp;등이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이를 위해 &lt;b&gt;API Gateway + lambda 로 해결&lt;/b&gt;하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;lambda 생성&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1709723377350&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export const handler = async (event) =&amp;gt; {

    let newLocation = &quot;https://www.lolduo.net&quot; + event.path;
    
    for(let key in event.queryStringParameters) {
        newLocation += (newLocation.includes(&quot;?&quot;) ? &quot;&amp;amp;&quot; : &quot;?&quot;) + key + &quot;=&quot; + event.queryStringParameters[key];
    }
    
    return {
        statusCode: 302,
        headers: { Location: newLocation }
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 들어온 요청을 새로운 &lt;a href=&quot;http://www.lolduo.net으로&quot;&gt;www.lolduo.net으로&lt;/a&gt; 변경하여 redirect 해주는 lambda를 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런뒤 생성한 Lambda에 API Gateway 트리거를 추가해주고, 모든 경로를 포함한다는 $default 경로를 추가합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;트리거 추가 및 경로 추가&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sED42/btsFBM8r9hb/O8iC5fgGLZZWG80fKFFsl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sED42/btsFBM8r9hb/O8iC5fgGLZZWG80fKFFsl1/img.png&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;1696&quot; data-is-animation=&quot;false&quot; style=&quot;width: 19.7323%; margin-right: 10px;&quot; data-widthpercent=&quot;19.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sED42/btsFBM8r9hb/O8iC5fgGLZZWG80fKFFsl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsED42%2FbtsFBM8r9hb%2FO8iC5fgGLZZWG80fKFFsl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1288&quot; height=&quot;1696&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA6Hib/btsFy8SdEUj/4FnkQfy7dL2TcBYTBsad7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA6Hib/btsFy8SdEUj/4FnkQfy7dL2TcBYTBsad7K/img.png&quot; data-origin-width=&quot;2600&quot; data-origin-height=&quot;854&quot; data-is-animation=&quot;false&quot; style=&quot;width: 79.1049%;&quot; data-widthpercent=&quot;80.04&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA6Hib/btsFy8SdEUj/4FnkQfy7dL2TcBYTBsad7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA6Hib%2FbtsFy8SdEUj%2F4FnkQfy7dL2TcBYTBsad7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2600&quot; height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;lamdba에 트리거 추가 및 추가한 API Gateway에 경로 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Gateway에서 사용자 지정 도메인 이름을 생성해야 Route53에서 사용이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 도메인 이름을 생성해주고 API 매핑에서 방금 생성해준 Lambda와 연동된 API Gateway를 추가해줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용자 지정 도메인 이름 생성 및 API 매핑&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czHhzM/btsFxWkopLZ/2O1UYIQQrgtNjqx5LJpri0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czHhzM/btsFxWkopLZ/2O1UYIQQrgtNjqx5LJpri0/img.png&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;2270&quot; data-is-animation=&quot;false&quot; style=&quot;width: 27.9328%; margin-right: 10px;&quot; data-widthpercent=&quot;28.26&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czHhzM/btsFxWkopLZ/2O1UYIQQrgtNjqx5LJpri0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczHhzM%2FbtsFxWkopLZ%2F2O1UYIQQrgtNjqx5LJpri0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1522&quot; height=&quot;2270&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwOCZ/btsFCA7mZnH/MMReYZ27zfNfCe1li7NqkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwOCZ/btsFCA7mZnH/MMReYZ27zfNfCe1li7NqkK/img.png&quot; data-origin-width=&quot;2444&quot; data-origin-height=&quot;1436&quot; data-is-animation=&quot;false&quot; style=&quot;width: 70.9044%;&quot; data-widthpercent=&quot;71.74&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwOCZ/btsFCA7mZnH/MMReYZ27zfNfCe1li7NqkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmwOCZ%2FbtsFCA7mZnH%2FMMReYZ27zfNfCe1li7NqkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2444&quot; height=&quot;1436&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;API Gateway 사용자 지정 도메인 이름 생성 및 API 매핑&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 Route53에서 방금 생성한 사용자 지정 도메인 이름을 매핑해주면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Route53 레코드 생성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;1462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRdBBt/btsFAv7eq6K/1MSKJjhozQHcdUq8mFkRMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRdBBt/btsFAv7eq6K/1MSKJjhozQHcdUq8mFkRMk/img.png&quot; data-alt=&quot;Route53의 레코드 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRdBBt/btsFAv7eq6K/1MSKJjhozQHcdUq8mFkRMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRdBBt%2FbtsFAv7eq6K%2F1MSKJjhozQHcdUq8mFkRMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2216&quot; height=&quot;1462&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;1462&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Route53의 레코드 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>API Gateway</category>
      <category>lambda</category>
      <category>netlify</category>
      <category>non www</category>
      <category>Redirect</category>
      <category>Route53</category>
      <category>www</category>
      <category>사용자 지정 도메인 이름</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/131</guid>
      <comments>https://imygnam.tistory.com/131#entry131comment</comments>
      <pubDate>Wed, 6 Mar 2024 20:36:02 +0900</pubDate>
    </item>
    <item>
      <title>[Java] GC 종류별 메모리 상황에 따른 테스트</title>
      <link>https://imygnam.tistory.com/130</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;특정 job 에 대해서 메모리를 설정해야하는데 이때 한번 GC를 종류별로 돌려보며 테스트를 해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 해당 job이 매우 짧게 끝나기도 하고 메모리를 적게 사용하며 CPU 사용율 등을 자세하게 확인하지 않았기에 가볍게 봐주시면 감사하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 환경은 Java17에 OpenJDK 이며 모니터링으로는 VisualVM + VisualGC 와 jstat을 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교한 GC는 SerialGC, ParallelGC, G1GC, ZGC로&amp;nbsp; Java17에서 지원하는 GC들 입니다. ShenandoahGC는 테스트하지 않았습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;목차&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;15MB [-Xms15m -Xmx15m]&lt;/li&gt;
&lt;li&gt;50MB [-Xms50m -Xmx50m]&lt;/li&gt;
&lt;li&gt;100MB [-Xms100m -Xmx100m]&lt;/li&gt;
&lt;li&gt;결론&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;15MB [ -Xms15m -Xmx15m ]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oracle에서도 100m 이하일때&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;SerialGC를 추천&lt;/b&gt;하는 이유가 확실히 보였습니다. 전체 GC시간이 가장 적은것이 SerialGC 였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;극단적으로 메모리를 낮추어&lt;/b&gt;봤을 때 예상외로 G1GC의 성능이 ParallelGC보다 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZGC는 OutOfMemory 발생으로 실행조차 되지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707379436240&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HotSpot Virtual Machine Garbage Collection Tuning Guide&quot; data-og-description=&quot;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; data-og-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HotSpot Virtual Machine Garbage Collection Tuning Guide&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SerialGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl5AEg/btsEDoO0tJC/qsS2h2O2V6kQGRlA7bl3K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl5AEg/btsEDoO0tJC/qsS2h2O2V6kQGRlA7bl3K1/img.png&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;1044&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.2407%; margin-right: 10px;&quot; data-widthpercent=&quot;44.76&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl5AEg/btsEDoO0tJC/qsS2h2O2V6kQGRlA7bl3K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl5AEg%2FbtsEDoO0tJC%2FqsS2h2O2V6kQGRlA7bl3K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1714&quot; height=&quot;1044&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdh3ys/btsEEB1nCV9/aOaEO12gFiVFONyROi2Gg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdh3ys/btsEEB1nCV9/aOaEO12gFiVFONyROi2Gg0/img.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;844&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.5965%;&quot; data-widthpercent=&quot;55.24&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdh3ys/btsEEB1nCV9/aOaEO12gFiVFONyROi2Gg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdh3ys%2FbtsEEB1nCV9%2FaOaEO12gFiVFONyROi2Gg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;844&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;SerialGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bODIxZ/btsEDqF3t9Z/39nNlY6spZ7irHEaeZJj80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bODIxZ/btsEDqF3t9Z/39nNlY6spZ7irHEaeZJj80/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bODIxZ/btsEDqF3t9Z/39nNlY6spZ7irHEaeZJj80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbODIxZ%2FbtsEDqF3t9Z%2F39nNlY6spZ7irHEaeZJj80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ParallelGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pb8Wd/btsEFdd67Ep/kAkQRUf1QTEMIc2NyG6WQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pb8Wd/btsEFdd67Ep/kAkQRUf1QTEMIc2NyG6WQk/img.png&quot; style=&quot;width: 35.862806847545215%;&quot; data-widthpercent=&quot;36.28&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;1468&quot; data-origin-width=&quot;1712&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pb8Wd/btsEFdd67Ep/kAkQRUf1QTEMIc2NyG6WQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpb8Wd%2FbtsEFdd67Ep%2FkAkQRUf1QTEMIc2NyG6WQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1712&quot; height=&quot;1468&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OYPMd/btsECv1BEIp/srGI0b9c69qk9mA0rv0mpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OYPMd/btsECv1BEIp/srGI0b9c69qk9mA0rv0mpk/img.png&quot; style=&quot;width: 62.97440245478035%;&quot; data-widthpercent=&quot;63.72&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;836&quot; data-origin-width=&quot;1712&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OYPMd/btsECv1BEIp/srGI0b9c69qk9mA0rv0mpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOYPMd%2FbtsECv1BEIp%2FsrGI0b9c69qk9mA0rv0mpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1712&quot; height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;ParallelGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b90Xnz/btsEFgvbltC/TeMREwXmFwGvfyajbZHEc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b90Xnz/btsEFgvbltC/TeMREwXmFwGvfyajbZHEc1/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b90Xnz/btsEFgvbltC/TeMREwXmFwGvfyajbZHEc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb90Xnz%2FbtsEFgvbltC%2FTeMREwXmFwGvfyajbZHEc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;G1GC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ysiIc/btsEEJLjg6I/9IuHIQb8wk1Zud8D9nwkL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ysiIc/btsEEJLjg6I/9IuHIQb8wk1Zud8D9nwkL0/img.png&quot; data-origin-width=&quot;1712&quot; data-origin-height=&quot;1040&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.3644%; margin-right: 10px;&quot; data-widthpercent=&quot;44.89&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ysiIc/btsEEJLjg6I/9IuHIQb8wk1Zud8D9nwkL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FysiIc%2FbtsEEJLjg6I%2F9IuHIQb8wk1Zud8D9nwkL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1712&quot; height=&quot;1040&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VUVr0/btsEA4RicG3/YJPHU9KDMRoAen0QJs0cw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VUVr0/btsEA4RicG3/YJPHU9KDMRoAen0QJs0cw0/img.png&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;848&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.4728%;&quot; data-widthpercent=&quot;55.11&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VUVr0/btsEA4RicG3/YJPHU9KDMRoAen0QJs0cw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVUVr0%2FbtsEA4RicG3%2FYJPHU9KDMRoAen0QJs0cw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1714&quot; height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;G1GC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zcLGc/btsEA1fYevn/LaMavoHTh5Stbc4RkrAmY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zcLGc/btsEA1fYevn/LaMavoHTh5Stbc4RkrAmY1/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zcLGc/btsEA1fYevn/LaMavoHTh5Stbc4RkrAmY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzcLGc%2FbtsEA1fYevn%2FLaMavoHTh5Stbc4RkrAmY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ZGC&lt;/h4&gt;
&lt;pre id=&quot;code_1707377176690&quot; class=&quot;julia&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;Exception in thread &quot;main&quot; java.lang.OutOfMemoryError: Java heap space&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;50MB [ -Xms50m -Xmx50m ]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Job이 필요로 하는 메모리가 적어서 그런지 여기서부터는 이제 큰 차이를 보이지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 ZGC가 사용가능해진 시점으로 &lt;b&gt;ZGC&lt;/b&gt;는 확실히 다른 GC들에 비해&lt;b&gt; GC 시간이 현저히 적었고&lt;/b&gt; SerialGC는 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;평균적으로 사용하는 메모리&lt;/b&gt;는 SerialGC와 ParallelGC에 비해 ZGC와 G1GC가 확실히 많이 사용하는 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SerialGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYtJ0y/btsEFdeq8VU/H2g6tsZkxnTVUGGyg8AwO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYtJ0y/btsEFdeq8VU/H2g6tsZkxnTVUGGyg8AwO1/img.png&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;1034&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.3608%; margin-right: 10px;&quot; data-widthpercent=&quot;44.88&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYtJ0y/btsEFdeq8VU/H2g6tsZkxnTVUGGyg8AwO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYtJ0y%2FbtsEFdeq8VU%2FH2g6tsZkxnTVUGGyg8AwO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1706&quot; height=&quot;1034&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bynIhU/btsEEwFPTZG/aeh6zt77QzHTTNH9dWzST0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bynIhU/btsEEwFPTZG/aeh6zt77QzHTTNH9dWzST0/img.png&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;842&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;55.12&quot; style=&quot;width: 54.4764%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bynIhU/btsEEwFPTZG/aeh6zt77QzHTTNH9dWzST0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbynIhU%2FbtsEEwFPTZG%2Faeh6zt77QzHTTNH9dWzST0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1706&quot; height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;SerialGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SkhCO/btsEBX5v9G6/f32zhEGgu2kc6hK0G8ZIg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SkhCO/btsEBX5v9G6/f32zhEGgu2kc6hK0G8ZIg0/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SkhCO/btsEBX5v9G6/f32zhEGgu2kc6hK0G8ZIg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSkhCO%2FbtsEBX5v9G6%2Ff32zhEGgu2kc6hK0G8ZIg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ParallelGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6hJOe/btsEEFbdBGU/cxwWWWKEPmvdiC5KBHgecK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6hJOe/btsEEFbdBGU/cxwWWWKEPmvdiC5KBHgecK/img.png&quot; style=&quot;width: 36.20909221355583%;&quot; data-widthpercent=&quot;36.64&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;1458&quot; data-origin-width=&quot;1710&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6hJOe/btsEEFbdBGU/cxwWWWKEPmvdiC5KBHgecK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6hJOe%2FbtsEEFbdBGU%2FcxwWWWKEPmvdiC5KBHgecK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;1458&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1dcHO/btsEClSrF4A/ZfCjwBJwmXZ3xHIAy3pivk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1dcHO/btsEClSrF4A/ZfCjwBJwmXZ3xHIAy3pivk/img.png&quot; style=&quot;width: 62.62811708876978%;&quot; data-widthpercent=&quot;63.36&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;840&quot; data-origin-width=&quot;1704&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1dcHO/btsEClSrF4A/ZfCjwBJwmXZ3xHIAy3pivk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1dcHO%2FbtsEClSrF4A%2FZfCjwBJwmXZ3xHIAy3pivk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1704&quot; height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;ParallelGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpbjsh/btsEEDYNhOj/s5JlKkpSOtD1OQKiocaGSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpbjsh/btsEEDYNhOj/s5JlKkpSOtD1OQKiocaGSk/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpbjsh/btsEEDYNhOj/s5JlKkpSOtD1OQKiocaGSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcpbjsh%2FbtsEEDYNhOj%2Fs5JlKkpSOtD1OQKiocaGSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;G1GC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4uIc7/btsECnvVBf3/TT1VjTCXp1SE6rxqtRcQyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4uIc7/btsECnvVBf3/TT1VjTCXp1SE6rxqtRcQyK/img.png&quot; data-origin-width=&quot;1710&quot; data-origin-height=&quot;1036&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.1116%; margin-right: 10px;&quot; data-widthpercent=&quot;44.63&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4uIc7/btsECnvVBf3/TT1VjTCXp1SE6rxqtRcQyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4uIc7%2FbtsECnvVBf3%2FTT1VjTCXp1SE6rxqtRcQyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;1036&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nudy6/btsEDrksRio/kF3ORhgYPGFIFmEsmcyj81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nudy6/btsEDrksRio/kF3ORhgYPGFIFmEsmcyj81/img.png&quot; data-origin-width=&quot;1716&quot; data-origin-height=&quot;838&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.7256%;&quot; data-widthpercent=&quot;55.37&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nudy6/btsEDrksRio/kF3ORhgYPGFIFmEsmcyj81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnudy6%2FbtsEDrksRio%2FkF3ORhgYPGFIFmEsmcyj81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1716&quot; height=&quot;838&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;G1GC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciYWIM/btsEE3bM2gX/zWBuh8CFi0AwjXX3I6uoY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciYWIM/btsEE3bM2gX/zWBuh8CFi0AwjXX3I6uoY1/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciYWIM/btsEE3bM2gX/zWBuh8CFi0AwjXX3I6uoY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciYWIM%2FbtsEE3bM2gX%2FzWBuh8CFi0AwjXX3I6uoY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ZGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1708&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vEfnr/btsEE3iAV3O/U3LR7S59SNpXkCaEq6Oho1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vEfnr/btsEE3iAV3O/U3LR7S59SNpXkCaEq6Oho1/img.png&quot; data-alt=&quot;ZGC의 VisualVM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vEfnr/btsEE3iAV3O/U3LR7S59SNpXkCaEq6Oho1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvEfnr%2FbtsEE3iAV3O%2FU3LR7S59SNpXkCaEq6Oho1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1708&quot; height=&quot;842&quot; data-origin-width=&quot;1708&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ZGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rb6RY/btsEDq0fjeS/nNu2lBiB2XtpPTk4HdnrMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rb6RY/btsEDq0fjeS/nNu2lBiB2XtpPTk4HdnrMk/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rb6RY/btsEDq0fjeS/nNu2lBiB2XtpPTk4HdnrMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frb6RY%2FbtsEDq0fjeS%2FnNu2lBiB2XtpPTk4HdnrMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;100MB [ -Xms100m -Xmx100m ]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50m와 크게 다를게 없어보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ZGC는 여전히 가장 빠른 GC 시간&lt;/b&gt;을 보여주며 &lt;b&gt;SerialGC는 여전히 느린&lt;/b&gt; 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SerialGC와 ParallelGC의 평균 메모리가 G1GC와 ZGC에 비해 덜 사용하는 것도 확인할 수 있었습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SerialGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/85FwB/btsEE16nQUM/88M4zFs8dZGBWxKZ2DAHH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/85FwB/btsEE16nQUM/88M4zFs8dZGBWxKZ2DAHH1/img.png&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;1036&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.1694%; margin-right: 10px;&quot; data-widthpercent=&quot;44.69&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/85FwB/btsEE16nQUM/88M4zFs8dZGBWxKZ2DAHH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F85FwB%2FbtsEE16nQUM%2F88M4zFs8dZGBWxKZ2DAHH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1700&quot; height=&quot;1036&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwdSCD/btsECtJRnBF/KDOwIG70Ve5V0FGNJyCIi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwdSCD/btsECtJRnBF/KDOwIG70Ve5V0FGNJyCIi0/img.png&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;840&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.6678%;&quot; data-widthpercent=&quot;55.31&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwdSCD/btsECtJRnBF/KDOwIG70Ve5V0FGNJyCIi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwdSCD%2FbtsECtJRnBF%2FKDOwIG70Ve5V0FGNJyCIi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1706&quot; height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;SerialGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HHLap/btsEEAO2BjX/G7IHAShsk2MKx9KKm8m6o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HHLap/btsEEAO2BjX/G7IHAShsk2MKx9KKm8m6o0/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HHLap/btsEEAO2BjX/G7IHAShsk2MKx9KKm8m6o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHHLap%2FbtsEEAO2BjX%2FG7IHAShsk2MKx9KKm8m6o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ParallelGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brvHf1/btsEBlL0RiE/XF4wEjZC95kgdKd5xkdYkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brvHf1/btsEBlL0RiE/XF4wEjZC95kgdKd5xkdYkk/img.png&quot; style=&quot;width: 36.26895854398382%;&quot; data-widthpercent=&quot;36.7&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;1456&quot; data-origin-width=&quot;1710&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brvHf1/btsEBlL0RiE/XF4wEjZC95kgdKd5xkdYkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrvHf1%2FbtsEBlL0RiE%2FXF4wEjZC95kgdKd5xkdYkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ka9FF/btsED4JjSyI/Xi8NNViqjWd95SiuvoO8O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ka9FF/btsED4JjSyI/Xi8NNViqjWd95SiuvoO8O0/img.png&quot; style=&quot;width: 62.56825075834176%;&quot; data-widthpercent=&quot;63.3&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;844&quot; data-origin-width=&quot;1710&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ka9FF/btsED4JjSyI/Xi8NNViqjWd95SiuvoO8O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKa9FF%2FbtsED4JjSyI%2FXi8NNViqjWd95SiuvoO8O0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1710&quot; height=&quot;844&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;ParallelGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lpMvb/btsEEDYJfqx/XNFkvC7qMvuNrvD5oRZU51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lpMvb/btsEEDYJfqx/XNFkvC7qMvuNrvD5oRZU51/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lpMvb/btsEEDYJfqx/XNFkvC7qMvuNrvD5oRZU51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlpMvb%2FbtsEEDYJfqx%2FXNFkvC7qMvuNrvD5oRZU51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;G1GC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dm4Oyc/btsEEEXEeTt/2VM25c4KsVxmFsxlheGTA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dm4Oyc/btsEEEXEeTt/2VM25c4KsVxmFsxlheGTA1/img.png&quot; data-origin-width=&quot;1712&quot; data-origin-height=&quot;1040&quot; data-is-animation=&quot;false&quot; style=&quot;width: 44.1293%; margin-right: 10px;&quot; data-widthpercent=&quot;44.65&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dm4Oyc/btsEEEXEeTt/2VM25c4KsVxmFsxlheGTA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdm4Oyc%2FbtsEEEXEeTt%2F2VM25c4KsVxmFsxlheGTA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1712&quot; height=&quot;1040&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ07BO/btsEEX3H4L9/ctbV1b4Oaxp7HmxKDhBtUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ07BO/btsEEX3H4L9/ctbV1b4Oaxp7HmxKDhBtUk/img.png&quot; data-origin-width=&quot;1702&quot; data-origin-height=&quot;834&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.7079%;&quot; data-widthpercent=&quot;55.35&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ07BO/btsEEX3H4L9/ctbV1b4Oaxp7HmxKDhBtUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ07BO%2FbtsEEX3H4L9%2FctbV1b4Oaxp7HmxKDhBtUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1702&quot; height=&quot;834&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;G1GC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HMQtH/btsEEVEQnZL/6X9NZEBFUCwNeEhM5Tyzn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HMQtH/btsEEVEQnZL/6X9NZEBFUCwNeEhM5Tyzn0/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HMQtH/btsEEVEQnZL/6X9NZEBFUCwNeEhM5Tyzn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHMQtH%2FbtsEEVEQnZL%2F6X9NZEBFUCwNeEhM5Tyzn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ZGC&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWJ4kY/btsEEzoOvb2/7NEi5ZOQpu5cAdKXFMQvC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWJ4kY/btsEEzoOvb2/7NEi5ZOQpu5cAdKXFMQvC1/img.png&quot; data-alt=&quot;ZGC의 VisualVM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWJ4kY/btsEEzoOvb2/7NEi5ZOQpu5cAdKXFMQvC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWJ4kY%2FbtsEEzoOvb2%2F7NEi5ZOQpu5cAdKXFMQvC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1714&quot; height=&quot;842&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ZGC의 VisualVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/df7xfZ/btsEEDEHGkg/WrOi5p8KzU0vRXK4qmfEZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/df7xfZ/btsEEDEHGkg/WrOi5p8KzU0vRXK4qmfEZK/img.png&quot; data-alt=&quot;jstat -gcutil의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/df7xfZ/btsEEDEHGkg/WrOi5p8KzU0vRXK4qmfEZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdf7xfZ%2FbtsEEDEHGkg%2FWrOi5p8KzU0vRXK4qmfEZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;58&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jstat -gcutil의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빡빡하게 테스트 환경을 조성하지 않았고, 적은 메모리 만으로도 비교해 보았음에도 각 &lt;b&gt;GC의 특징이 대략적으로나마 보이는 것&lt;/b&gt;이 신기하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZGC는 메모리를 확실히 많이 차지하는 한편 압도적인 GC 시간을 보여주었고, SerialGC와 ParallelGC는 상대적으로 적은 메모리 사용률을 보여주며 메모리에 여유가 생기자 ParallelGC가 SerialGC보다 더 나은 성능을 보여주는 것도 확인하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 세밀하게 들어가면 GC 튜닝 등 과정이 들어가겠지만, 이정도 Job에서는 너무 오버엔지니어링 같고 필요성이 느껴지면 그때 학습하여 적용하는 것이 좋겠다는 생각하에 여기서 마무리하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 어떠한 작업을 하고 나서는 반드시 GC에 대해 고민정도는 해야겠다는 생각이 확고하게 드는 테스트였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707381101653&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HotSpot Virtual Machine Garbage Collection Tuning Guide&quot; data-og-description=&quot;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; data-og-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HotSpot Virtual Machine Garbage Collection Tuning Guide&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Java</category>
      <category>G1GC</category>
      <category>GC</category>
      <category>Java</category>
      <category>memory</category>
      <category>parallelGC</category>
      <category>SerialGC</category>
      <category>test</category>
      <category>Time</category>
      <category>VS</category>
      <category>ZGC</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/130</guid>
      <comments>https://imygnam.tistory.com/130#entry130comment</comments>
      <pubDate>Thu, 8 Feb 2024 17:40:20 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 버전별 GC 목록 ( OpenJDK )</title>
      <link>https://imygnam.tistory.com/129</link>
      <description>&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;GC 확인 방법&lt;/li&gt;
&lt;li&gt;Java8의 GC&lt;/li&gt;
&lt;li&gt;Java11의 GC&lt;/li&gt;
&lt;li&gt;Java17의 GC&lt;/li&gt;
&lt;li&gt;Java21의 GC&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GC 확인 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Default 로 적용된 GC를 확인하는 방법은 크게 2가지로 다음과 같습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 적용중인 Flag를 확인하는 방법&lt;/h4&gt;
&lt;pre id=&quot;code_1707291730519&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -XX:+PrintCommandLineFlags -version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어로 현재 적용중인 Flag들과 버전을 같이 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2202&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uLqxZ/btsEA4WhXdX/Tv0tLzGgEMx3aNklq7Y691/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uLqxZ/btsEA4WhXdX/Tv0tLzGgEMx3aNklq7Y691/img.png&quot; data-alt=&quot;Java8에서의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uLqxZ/btsEA4WhXdX/Tv0tLzGgEMx3aNklq7Y691/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuLqxZ%2FbtsEA4WhXdX%2FTv0tLzGgEMx3aNklq7Y691%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2202&quot; height=&quot;140&quot; data-origin-width=&quot;2202&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java8에서의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 결과가 나오는데 Java8의 경우 ParallelGC를 사용하는 것으로 확인됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 전체 Flag를 확인하는 방법&lt;/h4&gt;
&lt;pre id=&quot;code_1707291981715&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -XX:+PrintFlagsFinal -version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어로 사용 가능한 Flag들과 현재 그 값들을 확인할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;grep 명령어와 함께 사용하여 GC 목록들만 뽑아서 확인하면 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;java8.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; data-alt=&quot;Java8 의 GC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUREe%2FbtsEBli9HKr%2Fl9NIaYkc9GPFja16gfbvXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1406&quot; height=&quot;570&quot; data-filename=&quot;java8.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java8 의 GC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Java8 에서의 GC&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;java8.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; data-alt=&quot;Java8 의 GC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUREe/btsEBli9HKr/l9NIaYkc9GPFja16gfbvXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUREe%2FbtsEBli9HKr%2Fl9NIaYkc9GPFja16gfbvXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1406&quot; height=&quot;570&quot; data-filename=&quot;java8.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java8 의 GC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 이미지를 잘 살펴보면 Java8에서는 크게 5가지의 GC를 확인할 수 있습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ConcMarkSweepGC &amp;amp; ParNewGC&lt;/li&gt;
&lt;li&gt;G1GC&lt;/li&gt;
&lt;li&gt;ParallelGC&lt;/li&gt;
&lt;li&gt;ParallelOldGC&lt;/li&gt;
&lt;li&gt;SerialGC&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Default GC는 ParallelGC&lt;/b&gt;인데 자세히 확인해보시면 ParallelGC와 ParallelOldGC가 동시에 활성화 되있는 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707292707617&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;java&quot; data-og-description=&quot;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;찾은 것이 비록 Oracle 이지만 &lt;b&gt;ParallelGC 옵션은&lt;/b&gt; 추가로 설정을 하지 않는 이상&lt;b&gt; ParallelOldGC 옵션을 활성화&lt;/b&gt; 시키며 ParallelOldGC는 ParallelGC를 자동으로 활성화 시킨다고 되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 ParallelGC만을 활성화는 가능하지만 ParallelOldGC만 활성화는 불가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2834&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VgbXV/btsEyRwXGix/WleC1pkuiWwPUjUc9ot1S1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VgbXV/btsEyRwXGix/WleC1pkuiWwPUjUc9ot1S1/img.png&quot; data-alt=&quot;ParallelGC 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VgbXV/btsEyRwXGix/WleC1pkuiWwPUjUc9ot1S1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVgbXV%2FbtsEyRwXGix%2FWleC1pkuiWwPUjUc9ot1S1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2834&quot; height=&quot;306&quot; data-origin-width=&quot;2834&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ParallelGC 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한&lt;b&gt; ConcMarkSweepGC는 활성화 시 ParNewGC가 자동으로 활성화&lt;/b&gt; 되고 역으로도 마찬가지라고 설명이 되어있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2658&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp1cqn/btsEy3jDPeQ/FoPPk3yRqmjKRhYmqjXGwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp1cqn/btsEy3jDPeQ/FoPPk3yRqmjKRhYmqjXGwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp1cqn/btsEy3jDPeQ/FoPPk3yRqmjKRhYmqjXGwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp1cqn%2FbtsEy3jDPeQ%2FFoPPk3yRqmjKRhYmqjXGwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2658&quot; height=&quot;256&quot; data-origin-width=&quot;2658&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2672&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZDnCu/btsEysw7FTI/ehBI9uIsylZKa2SVLKUdSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZDnCu/btsEysw7FTI/ehBI9uIsylZKa2SVLKUdSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZDnCu/btsEysw7FTI/ehBI9uIsylZKa2SVLKUdSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZDnCu%2FbtsEysw7FTI%2FehBI9uIsylZKa2SVLKUdSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2672&quot; height=&quot;152&quot; data-origin-width=&quot;2672&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Java11에서의 GC&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;java11.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V9OBs/btsEAUM7BbU/8KUNQCxINYPGH2xUgNeWz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V9OBs/btsEAUM7BbU/8KUNQCxINYPGH2xUgNeWz0/img.png&quot; data-alt=&quot;Java11 의 GC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V9OBs/btsEAUM7BbU/8KUNQCxINYPGH2xUgNeWz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV9OBs%2FbtsEAUM7BbU%2F8KUNQCxINYPGH2xUgNeWz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1642&quot; height=&quot;486&quot; data-filename=&quot;java11.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java11 의 GC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java11에서도 5개의 GC가 확인됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ConcMarkSweepGC&lt;/li&gt;
&lt;li&gt;G1GC&lt;/li&gt;
&lt;li&gt;ParallelGC&lt;/li&gt;
&lt;li&gt;ParallelOldGC&lt;/li&gt;
&lt;li&gt;SerialGC&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java11에서는 &lt;b&gt;Default GC가 G1GC&lt;/b&gt;이며 ParNewGC가 사라졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 Oracle 에서는 ZGC도 확인이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2458&quot; data-origin-height=&quot;994&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwLL3/btsEyOG7gL6/8O9cUsCTPyk2RW74PkuTZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwLL3/btsEyOG7gL6/8O9cUsCTPyk2RW74PkuTZ1/img.png&quot; data-alt=&quot;Oracle Java11에서 ZGC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwLL3/btsEyOG7gL6/8O9cUsCTPyk2RW74PkuTZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmwLL3%2FbtsEyOG7gL6%2F8O9cUsCTPyk2RW74PkuTZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2458&quot; height=&quot;994&quot; data-origin-width=&quot;2458&quot; data-origin-height=&quot;994&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Oracle Java11에서 ZGC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707293849485&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HotSpot Virtual Machine Garbage Collection Tuning Guide&quot; data-og-description=&quot;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; data-og-url=&quot;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HotSpot Virtual Machine Garbage Collection Tuning Guide&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Java17에서의 GC&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;java17.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cL2LEv/btsEx9dqYpo/HNQCGQJzBA1OcjQYfuQFKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cL2LEv/btsEx9dqYpo/HNQCGQJzBA1OcjQYfuQFKK/img.png&quot; data-alt=&quot;Java17의 GC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cL2LEv/btsEx9dqYpo/HNQCGQJzBA1OcjQYfuQFKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcL2LEv%2FbtsEx9dqYpo%2FHNQCGQJzBA1OcjQYfuQFKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1638&quot; height=&quot;398&quot; data-filename=&quot;java17.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java17의 GC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java17에서부터는 ZGC와 ShenandoahGC가 보이기 시작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Default GC는 그대로 G1GC&lt;/b&gt;이며 ParallelOldGC가 ParallelGC로 병합되어서 따로 존재하지 않습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;G1GC&lt;/li&gt;
&lt;li&gt;ParallelGC&lt;/li&gt;
&lt;li&gt;SerialGC&lt;/li&gt;
&lt;li&gt;ShenandoahGC&lt;/li&gt;
&lt;li&gt;ZGC&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 Oracle에서는 ShenandoahGC가 확인되지 않는데 이는 Openjdk 홈페이지에서도 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qxLwd/btsEB0eRZxq/M3wgcH31qAdQvDmf1IY7WK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qxLwd/btsEB0eRZxq/M3wgcH31qAdQvDmf1IY7WK/img.png&quot; data-alt=&quot;ShenandoahGC의 Releases&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qxLwd/btsEB0eRZxq/M3wgcH31qAdQvDmf1IY7WK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqxLwd%2FbtsEB0eRZxq%2FM3wgcH31qAdQvDmf1IY7WK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2056&quot; height=&quot;930&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ShenandoahGC의 Releases&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707293932466&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HotSpot Virtual Machine Garbage Collection Tuning Guide&quot; data-og-description=&quot;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; data-og-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/en/java/javase/17/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HotSpot Virtual Machine Garbage Collection Tuning Guide&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The discussion to this point has been about the serial collector. The Java HotSpot VM includes three different types of collectors, each with different performance characteristics.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wiki.openjdk.org/display/shenandoah/Main&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wiki.openjdk.org/display/shenandoah/Main&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707293999257&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Main
 - 

    Main
      - 
  
OpenJDK Wiki&quot; data-og-description=&quot;&quot; data-og-host=&quot;wiki.openjdk.org&quot; data-og-source-url=&quot;https://wiki.openjdk.org/display/shenandoah/Main&quot; data-og-url=&quot;https://wiki.openjdk.org/display/shenandoah/Main&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://wiki.openjdk.org/display/shenandoah/Main&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wiki.openjdk.org/display/shenandoah/Main&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Main - Main - OpenJDK Wiki&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wiki.openjdk.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Java21에서의 GC&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;java21.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ztqS8/btsEydAdO4z/jYKPw1JcH2kLDYlGk91f9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ztqS8/btsEydAdO4z/jYKPw1JcH2kLDYlGk91f9k/img.png&quot; data-alt=&quot;Java21의 GC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ztqS8/btsEydAdO4z/jYKPw1JcH2kLDYlGk91f9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FztqS8%2FbtsEydAdO4z%2FjYKPw1JcH2kLDYlGk91f9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1646&quot; height=&quot;398&quot; data-filename=&quot;java21.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java21의 GC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java21에서도 동일하게 5개의 GC가 확인되며 &lt;b&gt;Default GC 또한 동일하게 G1GC&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;G1GC&lt;/li&gt;
&lt;li&gt;ParallelGC&lt;/li&gt;
&lt;li&gt;SerialGC&lt;/li&gt;
&lt;li&gt;ShenandoahGC&lt;/li&gt;
&lt;li&gt;ZGC&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Computer Science/Java</category>
      <category>default gc</category>
      <category>G1GC</category>
      <category>garbage collection</category>
      <category>GC</category>
      <category>Java</category>
      <category>parallelGC</category>
      <category>SerialGC</category>
      <category>ShenandoahGC</category>
      <category>ZGC</category>
      <category>기본 gc</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/129</guid>
      <comments>https://imygnam.tistory.com/129#entry129comment</comments>
      <pubDate>Wed, 7 Feb 2024 17:55:05 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] JVM 동작 방식</title>
      <link>https://imygnam.tistory.com/128</link>
      <description>&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;JVM이란&lt;/li&gt;
&lt;li&gt;Class Loader&lt;/li&gt;
&lt;li&gt;Execution Engine&lt;/li&gt;
&lt;li&gt;Runtime Data Areas&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;JVM이란&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 Java Virtual Machine의 약자로 &lt;b&gt;자바 바이트코드를 실행하는 가상 머신&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 Compile시 자바 Source Code가 바이트코드 ( .class 파일 ) 로 변환되며 이 바이트코드가 JVM에서 실행되는 구조입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;788&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v1Hjr/btsEybBhg8Z/bESjhusnMuVRusl5KXKn4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v1Hjr/btsEybBhg8Z/bESjhusnMuVRusl5KXKn4k/img.png&quot; data-alt=&quot;JVM 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v1Hjr/btsEybBhg8Z/bESjhusnMuVRusl5KXKn4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv1Hjr%2FbtsEybBhg8Z%2FbESjhusnMuVRusl5KXKn4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1400&quot; height=&quot;788&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;788&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JVM 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM ( Java Virtual Machine )의 동작 구조를 간단히 설명하면 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Class Loader는 실행할 프로그램의 Class를 Runtime Data Areas에 Load 합니다.&lt;/li&gt;
&lt;li&gt;Load 된 Class는 Execution Engine 에 의해 실행됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Class Loader&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3730&quot; data-origin-height=&quot;1034&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUsQLO/btsEuPFJIao/V1qJ5lZyDTa4gkK0WNwox0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUsQLO/btsEuPFJIao/V1qJ5lZyDTa4gkK0WNwox0/img.png&quot; data-alt=&quot;Class Loader 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUsQLO/btsEuPFJIao/V1qJ5lZyDTa4gkK0WNwox0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUsQLO%2FbtsEuPFJIao%2FV1qJ5lZyDTa4gkK0WNwox0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3730&quot; height=&quot;1034&quot; data-origin-width=&quot;3730&quot; data-origin-height=&quot;1034&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Class Loader 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Class Loader의 동작 방식을 자세히 보면 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;로딩&lt;/b&gt; ( Loading ) : Class Loader는 .class 파일을 &lt;b&gt;JVM의 메모리에 로드&lt;/b&gt;합니다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;자세하게는 바이너리 형태의 Class data 가 Method Area에 저장됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;링킹&lt;/b&gt; ( Linking )&amp;nbsp; : 로드된 Class data는 JVM에서 사용될 수 있도록 링킹 과정을 거치는데 크게 3가지 단계로 이루어집니다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;검증&lt;/b&gt; ( Verification )&amp;nbsp; : 로드된 Class가 &lt;b&gt;JVM의 안전한 실행을 위반하지 않는지 검사&lt;/b&gt;합니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 예를들어 형식의 안정성, 액세스 권한 위반 ( private 또는 protected 접근 ) 등을 확인합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;준비&lt;/b&gt; ( Preparation ) : Class 변수 ( Static 변수 ) 에 &lt;b&gt;메모리를 할당하고, 기본값으로 초기화&lt;/b&gt; 합니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이때 초기화하는 값은 타입에 따른 기본값 ( int의 경우 0 ) 을 할당합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해석&lt;/b&gt; ( Resolution )&amp;nbsp; &amp;nbsp;: 심볼릭 메모리 레퍼런스를 Method Area에 존재하는 &lt;b&gt;실제 레퍼런스로 교체&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;초기화&lt;/b&gt; ( Initialization ) : Class 변수들에 대해 &lt;b&gt;정의된 초기값을 설정&lt;/b&gt;합니다. 이 과정에서 정적 초기화 블록이 실행됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Execution Engine&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 엔진은 .class 파일의 바이트코드가 Class Loader에 의해 Load된 &lt;b&gt;바이트코드를 기계어로 변환하여 실행하는 역할&lt;/b&gt;을 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 엔진은 크게 3가지로 구성이 되어있는데 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인터프리터&lt;/b&gt; ( Interpreter ) : 바이트코드를 &lt;b&gt;한 줄씩 읽어서 바로 실행&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JIT&lt;/b&gt; ( Just-In-Time ) 컴파일러 : 인터프리터의 단점을 보완하기 위해 도입된 것으로 실행 되는 동안 &lt;b&gt;바이트코드의 핫스팟&lt;/b&gt;(HotSpot) 즉 반복적으로 실행되는 코드 부분을 &lt;b&gt;식별하고, 이를 기계어로 변환&lt;/b&gt;하여 실행 속도를 향상시키는 것입니다. &lt;br /&gt;변환된 코드는 캐시에 저장되어 있으며 이후 지속적으로 재사용됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가비지 컬렉터&lt;/b&gt; ( Garbage Collector ) : 프로그램 실행 중에 생성된 객체 중에서 &lt;b&gt;더 이상 참조되지 않는 객체를 자동으로 검출&lt;/b&gt;하고, 이를 &lt;b&gt;삭제하여 메모리를 관리&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Runtime Data Areas&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;617&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/61DRA/btsEvXXQeyN/rU0hggq5bcF9fjeUILkWW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/61DRA/btsEvXXQeyN/rU0hggq5bcF9fjeUILkWW1/img.png&quot; data-alt=&quot;Runtime Data Areas 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/61DRA/btsEvXXQeyN/rU0hggq5bcF9fjeUILkWW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F61DRA%2FbtsEvXXQeyN%2FrU0hggq5bcF9fjeUILkWW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1339&quot; height=&quot;617&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;617&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Runtime Data Areas 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Runtime Data Area는 Runtime 시에 사용하는 메모리 영역이며 크게 5개로 분류됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Method Area&lt;/b&gt; : 모든 스레드가 공유하는 영역으로, &lt;b&gt;클래스 정보&lt;/b&gt;를 가지고 있습니다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;각 클래스의 구조, 상수 풀, 정적 변수, 바이트코드 등 메타데이터가 저장되어 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Heap&lt;/b&gt; : 모든 스레드가 공유하는 영역으로, 대부분의 메모리를 차지합니다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;인스턴스 객체 및 배열 등 &lt;b&gt;동적으로 할당된 데이터&lt;/b&gt;를 저장합니다. GC ( Garbage Collection ) 이 이 영역에서 발생합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Stack&lt;/b&gt; : 각 스레드마다 하나씩 생성되며, 메소드 호출 및 실행을 관리합니다.&lt;br /&gt;각 &lt;b&gt;메소드 호출마다 Frame이 스택에 생성&lt;/b&gt;되며 Frame에는 로컬 변수, 결과 등이 담겨있습니다. &lt;br /&gt;메소드가 종료되면 Frame도 사라집니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PC Register&lt;/b&gt; ( Program Counter Register ) : 각 스레드마다 하나씩 생성되며, &lt;b&gt;현재 실행중인 JVM 명령의 주소를 관리&lt;/b&gt;합니다. 이로써 각 스레드가 현재 어느 명령어를 실행중인지 알 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Native Method Stack&lt;/b&gt; : 각 스레드마다 하나씩 생성되며, &lt;b&gt;Java가 아닌 다른 언어로 작성된 메소드를 관리&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Computer Science/Java</category>
      <category>class loader</category>
      <category>execution engine</category>
      <category>Heap</category>
      <category>JIT</category>
      <category>jvm</category>
      <category>method area</category>
      <category>native method stack</category>
      <category>pc register</category>
      <category>runtime data area</category>
      <category>Stack</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/128</guid>
      <comments>https://imygnam.tistory.com/128#entry128comment</comments>
      <pubDate>Tue, 6 Feb 2024 20:52:21 +0900</pubDate>
    </item>
    <item>
      <title>[LOL-DUO] Lamdba 로 데이터를 크롤링해 RDS 에 데이터 저장하기.</title>
      <link>https://imygnam.tistory.com/127</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 목표&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. 아키텍처 설계 과정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp;2.1&amp;nbsp; Lambda로 진행한 이유&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp;2.2 Lambda가 2개로 나뉘어진 이유&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp;2.3 JS로 진행한 이유&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. 개발 과정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp;3.1&amp;nbsp; VPC 내부에 Lambda 생성하기.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp;3.2 Lambda 함수 개발 ( JS )&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 목표&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. FreeTier 내에서 가능하도록 구현. ( &lt;b&gt;최소한의 비용&lt;/b&gt; )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. Riot 데이터를 가져와 가공하여 &lt;b&gt;RDS에 저장&lt;/b&gt;하기 및 내 &lt;b&gt;서버 상태 체크&lt;/b&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. &lt;b&gt;매 1시간&lt;/b&gt; 마다 돌며 결과를 Slack 으로 제공.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매 1시간 마다 Server의 상태 체크 등 정보를 가져와 Slack으로 알려주는 기능이 필요했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 주기적으로 Riot Data ( Version ) 등을 가져와 변경사항이 있다면 Database에 저장하고 알려주는 기능이 필요했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 이를 묶어서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;하나의 Job&lt;/b&gt;으로 만들고자 했고 Lambda가 적격이라 생각해 Lambda로 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 아키텍처 설계 과정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2510&quot; data-origin-height=&quot;1416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S0Qn7/btsC38tzQsv/5VP18gwkFxKe4A6SNvs08K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S0Qn7/btsC38tzQsv/5VP18gwkFxKe4A6SNvs08K/img.png&quot; data-alt=&quot;전체 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S0Qn7/btsC38tzQsv/5VP18gwkFxKe4A6SNvs08K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS0Qn7%2FbtsC38tzQsv%2F5VP18gwkFxKe4A6SNvs08K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2510&quot; height=&quot;1416&quot; data-origin-width=&quot;2510&quot; data-origin-height=&quot;1416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;전체 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 Lambda로 진행한 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 돌고 있는 Job들이 존재해서 그곳에 추가를 하는 방법도 있었지만 해당 Job들은 Server와 동일한 EC2에서 동작하고 있기에 Server 가 죽는 상황이면 Job들도 죽는 상황일 가능성이 매우 높습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Server의 상태를 지속적으로 알려주는 Job이 죽는다면 상태를 알 방법이 없기에 &lt;b&gt;Server와&amp;nbsp;분리할 필요가 있다고 판단&lt;/b&gt;하였고, &lt;b&gt;매시간 단기간만 동작&lt;/b&gt;하면 되기에 &lt;b&gt;Lambda를 선택&lt;/b&gt;하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 Lambda가 2개로 나뉘어진 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda는 &lt;b&gt;VPC 내에 생성한다면 Public Ip를 할당 받지 않습니다.&lt;/b&gt; 따라서 외부에 http 요청을 보낸다면 수신하지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;RDS와 EC2 Server는 Private하게 관리&lt;/b&gt;를 해야합니다. 따라서 RDS에 정보를 저장하고 EC2 Server 정보를 가져오려면 VPC 내부에 Lambda를 띄워주어야 하는데, 이러면 해당 Lambda는 Riot 정보를 가져오지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 Riot 정보를 가져오고 Slack으로 Webhook을 날려주는 Lambda와 DB에 정보를 저장하고 Server 상태를 가져오는 VPC 내부의 Lambda를 각각 생성하여 역할을 나누었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 VPC 내부에 Nat Gateway를 설치해서 해당 Lambda가 Riot 정보까지 가져오도록 할 수 있었지만 &lt;b&gt;Nat Gateway는 비용이 발생&lt;/b&gt;합니다. 1번 목표를 위해서 해당 방식보다는 Lambda를 2개로 나누는 것이 좋다고 판단하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VPC &lt;b&gt;내부&lt;/b&gt;에서 동작하는 Lambda는 &lt;b&gt;API Gateway와 연동&lt;/b&gt;되어 요청을 받으면 해당 정보를 DB에 저장, Server 정보를 가져와 반환해주는 API 형태로 만들었습니다. &lt;b&gt;최소한의 보안&lt;/b&gt;을 위해 특정 key값을 설정하였고, 해당 key가 아닌 요청은 무시하도록 설계하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VPC &lt;b&gt;외부&lt;/b&gt;에서 동작하는 Lambda는 API Gateway가 필요하지 않는데, 이는 &lt;b&gt;EventBridge&lt;/b&gt;가 1시간마다 동작시켜주면 되고 값을 반환할 필요가 없기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CifNv/btsC4InUOyF/tOovUA8KwYDU1nj6RNbo9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CifNv/btsC4InUOyF/tOovUA8KwYDU1nj6RNbo9k/img.png&quot; data-alt=&quot;특정 key가 아니라면 다음과 같이 400 Bad Request를 반환합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CifNv/btsC4InUOyF/tOovUA8KwYDU1nj6RNbo9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCifNv%2FbtsC4InUOyF%2FtOovUA8KwYDU1nj6RNbo9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1722&quot; height=&quot;238&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;특정 key가 아니라면 다음과 같이 400 Bad Request를 반환합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 JS로 진행한 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Riot 에서 제공하는 데이터가 Json 형태이기에 JS로 다루기도 편할 뿐더러 JS가 Lambda의 Cold Start Time도 낮은 편에 속해있기에 JS로 선택하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mikhail.io/serverless/coldstarts/aws/languages/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mikhail.io/serverless/coldstarts/aws/languages/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704524295450&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;AWS Lambda: Cold Start Duration per Language&quot; data-og-description=&quot;The following chart shows the typical range of cold starts in AWS Lambda, broken down per language. The darker ranges are the most common 67% of durations, and lighter ranges include 95%.&quot; data-og-host=&quot;mikhail.io&quot; data-og-source-url=&quot;https://mikhail.io/serverless/coldstarts/aws/languages/&quot; data-og-url=&quot;https://mikhail.io/serverless/coldstarts/aws/languages/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fQkee/hyUXZer8Bu/en6DvB7WcXEw59xogn8qO1/img.png?width=1015&amp;amp;height=587&amp;amp;face=0_0_1015_587,https://scrap.kakaocdn.net/dn/cpr2zq/hyU2pP6L3Q/4LKAW2M4tQC8UBuSCKCyik/img.png?width=1015&amp;amp;height=587&amp;amp;face=0_0_1015_587&quot;&gt;&lt;a href=&quot;https://mikhail.io/serverless/coldstarts/aws/languages/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mikhail.io/serverless/coldstarts/aws/languages/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fQkee/hyUXZer8Bu/en6DvB7WcXEw59xogn8qO1/img.png?width=1015&amp;amp;height=587&amp;amp;face=0_0_1015_587,https://scrap.kakaocdn.net/dn/cpr2zq/hyU2pP6L3Q/4LKAW2M4tQC8UBuSCKCyik/img.png?width=1015&amp;amp;height=587&amp;amp;face=0_0_1015_587');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda: Cold Start Duration per Language&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The following chart shows the typical range of cold starts in AWS Lambda, broken down per language. The darker ranges are the most common 67% of durations, and lighter ranges include 95%.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mikhail.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 개발 과정&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 VPC 내부에 Lambda 생성하기.&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TGMX4/btsC2whd2Ra/v8YpW0xcmB92EygGt63opK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TGMX4/btsC2whd2Ra/v8YpW0xcmB92EygGt63opK/img.png&quot; data-origin-width=&quot;2480&quot; data-origin-height=&quot;1542&quot; data-is-animation=&quot;false&quot; style=&quot;width: 52.9872%; margin-right: 10px;&quot; data-widthpercent=&quot;53.61&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TGMX4/btsC2whd2Ra/v8YpW0xcmB92EygGt63opK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTGMX4%2FbtsC2whd2Ra%2Fv8YpW0xcmB92EygGt63opK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2480&quot; height=&quot;1542&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rLdg4/btsC55DbADM/UpApJDUTKHwZz1UuAsBynK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rLdg4/btsC55DbADM/UpApJDUTKHwZz1UuAsBynK/img.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.85%;&quot; data-widthpercent=&quot;46.39&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rLdg4/btsC55DbADM/UpApJDUTKHwZz1UuAsBynK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrLdg4%2FbtsC55DbADM%2FUpApJDUTKHwZz1UuAsBynK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2004&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;Lambda 함수와 역할&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda를 VPC 내부에 띄우려면 AWSLambdaVPCAccessExecutionRole 권한이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 권한은 Lamdba에 부여된 역할에서 권한 추가를 해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런뒤 다시 구성에서 VPC에 들어가 배포할 VPC로 편집해주면 해당 VPC로 Lambda가 배포됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Gateway는 트리거 추가를 통해 손쉽게 부착할 수 있습니다. EventBridge 또한 마찬가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EventBridge의 Cron 표현식 사용법은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704524936876&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Cron expressions reference - Amazon EventBridge&quot; data-og-description=&quot;If you use a '#' character, you can define only one expression in the day-of-week field. For example, &amp;quot;3#1,6#3&amp;quot; is not valid because it is interpreted as two expressions.&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Cron expressions reference - Amazon EventBridge&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;If you use a '#' character, you can define only one expression in the day-of-week field. For example, &quot;3#1,6#3&quot; is not valid because it is interpreted as two expressions.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2 Lambda 함수 개발 ( JS )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda는 &lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: left;&quot;&gt;index.handler를 실행합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: left;&quot;&gt;handler에 input 또한 전달해주기 때문에 API Gateway를 통해 들어온 정보를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704523872822&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AWS Lambda 함수 핸들러(Node.js) - AWS Lambda&quot; data-og-description=&quot;AWS Lambda 함수 핸들러(Node.js) Lambda 함수의 핸들러는 이벤트를 처리하는 함수 코드의 메서드입니다. 함수가 호출되면 Lambda는 핸들러 메서드를 실행합니다. 함수는 핸들러가 응답을 반환하거나 종&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda 함수 핸들러(Node.js) - AWS Lambda&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda 함수 핸들러(Node.js) Lambda 함수의 핸들러는 이벤트를 처리하는 함수 코드의 메서드입니다. 함수가 호출되면 Lambda는 핸들러 메서드를 실행합니다. 함수는 핸들러가 응답을 반환하거나 종&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 API Gateway를 사용하는 Lambda의 코드는 다음과 같이 구성하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 개발은 local에서 진행 후 zip으로 node_modules와 함께 파일들을 묶어 올리는 형태로 진행하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1704524649024&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// lambda 코드 
class app {
    async start() {
        // logic
    }
}
export const handler = async (event, context) =&amp;gt; {

    //key check 과정 진행
	
    let body = JSON.parse(event.body); // body parse;
    let result = await new app().start(body.info, ...); // db 저장 및 server 정보 획득
    return {
          statusCode: 200,
          body: JSON.stringify(result),
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트</category>
      <category>AWS</category>
      <category>cron</category>
      <category>EC2</category>
      <category>eventbridge</category>
      <category>lambda</category>
      <category>lol-duo</category>
      <category>RDS</category>
      <category>VPC</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/127</guid>
      <comments>https://imygnam.tistory.com/127#entry127comment</comments>
      <pubDate>Sat, 6 Jan 2024 16:24:42 +0900</pubDate>
    </item>
    <item>
      <title>쿠키 ( Cookie ), 세션 ( Session )</title>
      <link>https://imygnam.tistory.com/126</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키와 세션은 웹 통신을 함에 있어 사용되는 개념으로, 사용자의 &lt;b&gt;웹 브라우저와 웹 서버간의 상태 정보를 관리하고 유지하는데 사용&lt;/b&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 통신은 기본적으로 HTTP 프로토콜을 사용하는데, Stateless 환경이기 때문에 상태 정보를 가지고 있을 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 보완하기 위해 사용되는 것이 쿠키와 세션입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘의 공통점으로는 사용자의 정보를 저장하여 사용한다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;매번 인증 등을 진행하지 않고 사용자 정보를 제공한다는 점에서 장점&lt;/b&gt;이지만 &lt;b&gt;보안을 신경써야한다는 점&lt;/b&gt;이 따라붙습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘의 가장 큰 차이점은 &lt;b&gt;쿠키는 클라이언트&lt;/b&gt; 쪽에서 관리가 되며, &lt;b&gt;세션은 서버 &lt;/b&gt;쪽에서 관리가 된다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로인해 보안은 세션이 조금 더 좋으며 쿠키를 사용할 때에는 암호화 등을 진행하는 것이 좋습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 쿠키 ( Cookie )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키는 클라이언트 ( 웹 브라우저 ) 에 저장되는 작은 데이터입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트에 저장되므로 서버에 의존하지 않고 정보를 유지할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름(key), 값(value), 만료일, 경로 등의 정보를 담고 있으며 도메인당 최대 20개를 저장할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 세션 ( Session )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션은 서버에 저장하는 쿠키라고 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 쿠키와 함께 사용되지만 세션 ID를 서버에 전송할 수 만 있다면 쿠키가 아니어도 상관없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션 ID를 통해 데이터를 관리하며 보통 레디스 같은 메모리 DB를 통해 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science</category>
      <category>Cookie</category>
      <category>session</category>
      <category>web</category>
      <category>세션</category>
      <category>쿠키</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/126</guid>
      <comments>https://imygnam.tistory.com/126#entry126comment</comments>
      <pubDate>Fri, 5 Jan 2024 10:31:32 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Java version 별 차이 ( 7, 8, 9, 11 )</title>
      <link>https://imygnam.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;java 7 - 다이아몬드 연산자 지원, switch 문에서 String 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;java 8 - LTS 버전, Default Method, 람다 표현식, 함수형 Method, Optional 구조체, java.time 패키지, Stream API, GC 개선&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;java 9 - Java Platform Module System ( jigsaw project ), G1 GC, HTTP/2&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;java 11 - LTS 버전, HTTP/2 강화, 람다 표현식에 로컬 변수 타입 추론 추가&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;java 7&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 7 부터 제네렉에서 사용하는 &amp;lt;&amp;gt; 오퍼레이터 ( 다이아몬드 연산자 ) 를 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이아몬드 연산자를 사용하면 코드를 간결하게 만들고 가독성을 향상시킬 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702213037236&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;(); // jdk 7 이전
List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;(); // jdk 7 이후&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;switch 문에서 String 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 원시 자료형 또는 Enum 자료형만 사용 가능했지만 jdk 7 이후로는 String도 사용가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;java 8&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LTS 버전 입니다. 8 버전에서 큰 변화가 일어났습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 인터페이스 ( interface ) 에서 Default Method&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본래 인터페이스에서는 메서드의 정의만 가능하고 구현은 불가능하였습니다. 하지만 jdk 8 이후부터는 default 메서드가 생겨났으며 기존 메서드와는 다르게 인터페이스에서 구현이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로서 얻는 이득으로 가장 큰 것은 역호환성 유지입니다. 본래 기존 인터페이스에 새로운 메서드를 추가하려고 한다면 해당 인터페이스를 사용하는 다른 프로젝트와의 호환성 문제가 발생할 수 있습니다. 이를 default 메서드 사용을 통해 해결 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 람다 표현식, 함수형 인터페이스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다 표현식은 간결하게 익명 함수를 정의하고 전달하는 방식입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;람다 표현식은 주로 함수형 인터페이스에서 사용되는데 함수형 인터페이스란 추상 메서드가 오직 하나인 인터페이스를 의미합니다. 따라서 default 메서드 또는 static 메서드가 여러개여도 상관이 없습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. Optional 구조체&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 NullPointerException 이슈를 효율적으로 대응하기 위해 Optional 구조체가 추가되었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;4. java.time 패키지&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 java.util.Date 와 java.util.Calender 는 일관성, 정확성, 타임존 등의 문제점을 가지고 있었습니다. 이를 java.time 패키지 추가로 해결하였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5. Stream API&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터를 처리하고 가공하는 데 편리한 Stream API 가 jdk 8 부터 도입되었습니다. Stream을 이용하면 코드를 간결하고 가독성 있게 작성하면서도 손쉽게 병렬 처리 작업을 할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6. GC 성능 개선&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;java 8 이전에는 PermGen 이라는 메모리 영역이 존재하였는데 클래스와 메타데이터 ( 메서드, 필드, 주석 등 ) 을 저장하는 공간이었습니다. 다만 문제는 이것이 고정된 크기여서 클래스 및 메타데이터의 크기가 동적으로 변화하더라도 확장 등이 일어나지 않았습니다. 이를 해결하기 위해 PermGen 영역이 삭제되고 Metaspace 영역 ( Natvice Memory )이 새로 생겨났으며 GC 대상이 되도록 변경하였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;java 9&lt;/h3&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. Java Platform Module System ( jigsaw project )&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존에는 의존성 등이 명시적으로 정의되지 않았기에 클래스, 버전 충돌 등 문제가 있었습니다. 이를 해결하기 위해 도입된 프로젝트로 특징은 다음과 같습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 모듈화&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션을 독립적인 모듈로 나누고, 각 모듈은 자체적으로 의존성을 관리합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 의존성 관리&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 모듈은 의존성을 명시적으로 정의하고, 컴파일 타임 및 런타임에서 이러한 의존성을 체크합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. G1 GC&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기본 GC가 Parallel GC 에서 G1 GC 로 변경 되었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. HTTP/2 지원&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;java 9 에서 HTTP/2 프로토콜을 지원합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;java 11&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LTS 버전입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. HTTP/2 강화&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;java 11에서 HTTP/2 지원이 강화되었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 람다 표현식에서 로컬 변수 타입 추론 ( var )&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;java 11에서 로컬 변수 타입 추론을 지원하는 var 키워드가 도입되었습니다.&lt;/p&gt;</description>
      <category>Computer Science</category>
      <category>Java</category>
      <category>Version</category>
      <category>버전</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/124</guid>
      <comments>https://imygnam.tistory.com/124#entry124comment</comments>
      <pubDate>Tue, 12 Dec 2023 23:18:16 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] Type Compatibility ( 타입 호환성 )</title>
      <link>https://imygnam.tistory.com/123</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;타입 호환성이란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 타입 간에 비교를 통해 값이 할당 가능한지 여부를 나타내는 것 입니다. 즉 다른 타입이 해당 타입안에 들어올 수 있는지 판단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeScript의 타입 호환성은 명목적 타이핑 ( nominal typing )이 아닌 &lt;b&gt;구조적 서브 타이핑&lt;/b&gt; ( subtyping ) 을 기반으로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조적 타이핑이란 오직 &lt;b&gt;맴버만으로 타입을 확인&lt;/b&gt;하는 방식입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702128931298&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface test1 {
    test: string;
}

class test2 {
    test: string;
}

let test3: test1;

test3 = new test2(); // 맴버가 같기에 가능합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;함수의 비교&lt;/h4&gt;
&lt;pre id=&quot;code_1702129140532&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let first = (test: string) =&amp;gt; &quot;test&quot;;
let second = (test: string, test2: string) =&amp;gt; &quot;test&quot;;

second = first; // OK
first = second; // Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의 비교에서는 &lt;b&gt;매개변수를 서로 비교&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;second는 first의 모든 매개변수를 가지고 있기에 호환이 가능하지만 first는 second의 test2 를 가지고 있지 않기에 에러를 반환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;열거형의 비교&lt;/h4&gt;
&lt;pre id=&quot;code_1702129410847&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum Test1 {
    A,
    B,
    C,
}

enum Test2 {
    A = 1,
    B,
    C,
}

let test = Test1.A;
test = Test1.B; // OK
test = Test2.A; // Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열거형은 단순하게 &lt;b&gt;다른 열거형 타입의 열거형과는 호환되지 않습니다&lt;/b&gt;. 다만 같은 열거형 내에서는 호환이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클래스의 비교&lt;/h4&gt;
&lt;pre id=&quot;code_1702129663147&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Test1 {
    test: string;
    testFunc() {
        console.log(&quot;test&quot;);
    }

    constructor(test1: string, test2: string) {
        this.test = test1;
    }
}

class Test2 {
    test: string;
    static test2: string;
    testFunc() {
        console.log(&quot;test&quot;);
    }

    constructor(test1: string) {
        this.test = test1;
    }
}

let firstTest: Test1;
let secondTest: Test2;

firstTest = secondTest; // OK
secondTest = firstTest; // OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 타입의 비교는 오직 &lt;b&gt;인스턴스의 맴버만 비교&lt;/b&gt;를 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 정적 맴버 ( static ) 과 생성자 ( constructor ) 는 호환성에 영향을 주지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제네릭의 비교&lt;/h4&gt;
&lt;pre id=&quot;code_1702129926458&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Test&amp;lt;T&amp;gt; {}
let test1: Test&amp;lt;string&amp;gt;;
let test2: Test&amp;lt;number&amp;gt;;

test1 = test2; // OK
test2 = test1; // OK



interface Test&amp;lt;T&amp;gt; {
    test: T;
}
let test1: Test&amp;lt;string&amp;gt;;
let test2: Test&amp;lt;number&amp;gt;;

test1 = test2; // Error
test2 = test1; // Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제네릭 타입에서 중요한 것은 결국 &lt;b&gt;결과 타입&lt;/b&gt;입니다. 들어가는 Type이 중요한 것이 아닌 결과 인자를 비교합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 처음 호환은 전부 가능하지만 두번째부터는 불가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Freshness ( 신선도 ) 란&lt;/h4&gt;
&lt;pre id=&quot;code_1702130169341&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type Test = {
    name: string;
    age: number;
}

function testFunction(test: Test) {
    console.log(test.name);
}

let testInput = {
    name: 'test',
    age: 10,
    test: 'test'
}

testFunction(testInput); // OK
testFunction({ name: 'test', age: 10 }); // OK
testFunction({ name: 'test', age: 10, test: 'test' }); // Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeScript는 신선도라는 개념을 제공하는데, 모든 object literal 은 초기에 &quot;fresh&quot; 로 간주합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 type assertion ( 타입 단언 )을 하거나, 타입 추론에 의해 object literal 의 타입이 확장되면 &quot;fresh&quot; 가 사라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;fresh&quot; 상태에서는 타입호환을 허용하지 않습니다.&lt;/b&gt; 그렇기에 위와 같은 경우에서 마지막에는 Error가 발생합니다.&lt;/p&gt;</description>
      <category>Computer Science</category>
      <category>type compatibility</category>
      <category>Typescript</category>
      <category>타입 호환성</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/123</guid>
      <comments>https://imygnam.tistory.com/123#entry123comment</comments>
      <pubDate>Sat, 9 Dec 2023 23:02:28 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] Object VS Map ( 성능 비교 )</title>
      <link>https://imygnam.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701525106934&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Map - JavaScript | MDN&quot; data-og-description=&quot;Map 객체는 키-값 쌍과 키의 원래 삽입 순서를 기억합니다. 모든 값(객체 및 원시 값 모두)은 키 또는 값으로 사용될 수 있습니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bgLq1T/hyUFev1kaj/M9QdqBvpi9KdCzbbwQAKd1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bgLq1T/hyUFev1kaj/M9QdqBvpi9KdCzbbwQAKd1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Map - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Map 객체는 키-값 쌍과 키의 원래 삽입 순서를 기억합니다. 모든 값(객체 및 원시 값 모두)은 키 또는 값으로 사용될 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Object&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키를 문자열 또는 심볼로만 가질 수 있는 구조입니다. 위 링크에서도 나와있지만 Object는 역사적으로 Map으로 사용되어왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Map&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key, value 형태로 저장 가능한 자료구조로써 빠른 검색 등에 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Object와는 다르게 키의 데이터 유형에 제약이 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map은 Object를 상속하여 사용합니다. 하지만 당연하게도 Object는 Map을 상속하지는 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 여기서 조금 주의해서 보아야 할 것은 &lt;b&gt;Map에서 키는 삽입한 순서대로 정렬&lt;/b&gt;하여 가지고 있다는 점입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701525033146&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = {};
const map = new Map();
console.log(map instanceof Object); // true
console.log(obj instanceof Map); // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 단순 생각하기에는 Object나 Map이 성능면에서 비슷할 것이라고 생각하겠지만 실상은 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크에서도 성능 면에서 &lt;b&gt;키-값 쌍의 빈번한 추가 및 제거와 관련된 상황에서 성능이 좀 더 좋습니다.&lt;/b&gt; 라고 이야기하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 그러한지 테스트를 해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701523511879&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// random array of 1000000 numbers
let arr = new Array(1000000);
for (let i = 0; i &amp;lt; arr.length; i++) {
    arr[i] = Math.random() * 1000;
}
console.log(&quot;테스트 시작&quot;);

// let arr = new Array(1000000);
// for (let i = 0; i &amp;lt; arr.length; i++) {
//     arr[i] = &quot;key&quot; + Math.floor(Math.random() * arr.length);
// }
// console.log(&quot;문자 테스트 시작&quot;);

// let arr = new Array(1000000);
// for (let i = 0; i &amp;lt; arr.length; i++) {
//     arr[i] = Symbol(Math.random());
// }
// console.log(&quot;심볼 테스트 시작&quot;);

const startTime = Date.now();
let obj = {};
for (let i = 0; i &amp;lt; arr.length; i++) {
    obj[arr[i]] = arr[i];
}
const endTime = Date.now();
console.log(`object 삽입 시간: ${endTime - startTime}ms`);

const startTime2 = Date.now();
let map = new Map();
for (let i = 0; i &amp;lt; arr.length; i++) {
    map.set(arr[i], arr[i]);
}
const endTime2 = Date.now();
console.log(`map 삽입 시간: ${endTime2 - startTime2}ms`);

const startTime3 = Date.now();
for (let i = 0; i &amp;lt; arr.length; i++) {
    let a = obj[arr[i]];
}
const endTime3 = Date.now();
console.log(`object 검색 시간: ${endTime3 - startTime3}ms`);

const startTime4 = Date.now();
for (let i = 0; i &amp;lt; arr.length; i++) {
    let a = map.get(arr[i]);
}
const endTime4 = Date.now();

console.log(`map 검색 시간: ${endTime4 - startTime4}ms`);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmSoAR/btsBikPOHvL/ZB99MOJX24lgdr1fcar9OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmSoAR/btsBikPOHvL/ZB99MOJX24lgdr1fcar9OK/img.png&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;236&quot; data-is-animation=&quot;false&quot; style=&quot;width: 34.0934%; margin-right: 10px;&quot; data-widthpercent=&quot;34.91&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmSoAR/btsBikPOHvL/ZB99MOJX24lgdr1fcar9OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmSoAR%2FbtsBikPOHvL%2FZB99MOJX24lgdr1fcar9OK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;456&quot; height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJTYdM/btsBh4metkp/NvP2N5EKHxqR8BgvN7dxdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJTYdM/btsBh4metkp/NvP2N5EKHxqR8BgvN7dxdK/img.png&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;242&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.6648%; margin-right: 10px;&quot; data-widthpercent=&quot;33.44&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJTYdM/btsBh4metkp/NvP2N5EKHxqR8BgvN7dxdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJTYdM%2FbtsBh4metkp%2FNvP2N5EKHxqR8BgvN7dxdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Pc3S/btsBh65m1DW/DgTnzhnZSbQsjZGxAHlQcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Pc3S/btsBh65m1DW/DgTnzhnZSbQsjZGxAHlQcK/img.png&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;234&quot; data-is-animation=&quot;false&quot; style=&quot;width: 30.9162%;&quot; data-widthpercent=&quot;31.65&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Pc3S/btsBh65m1DW/DgTnzhnZSbQsjZGxAHlQcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Pc3S%2FbtsBh65m1DW%2FDgTnzhnZSbQsjZGxAHlQcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;각각 숫자와 문자, 심볼로 테스트 했을 때 출력된 시간입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 예상대로 Map이 훨씬 빠르게 나왔습니다. 숫자의 경우 삽입은 약 3.5배정도 차이를 보였으며 검색의 경우에는 25배까지 차이가 나는 것이 보였습니다. 이는 숫자의 경우 문자로 변경하는 작업이 들어가는 Object의 특성이 있기에 생기는 문제로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자의 경우에는 차이가 조금 덜 했습니다. 삽입의 경우 약 2.5배, 검색의 경우에는 4배정도 차이를 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심볼의 경우에는 더 좁혀졌는데, 삽입의 경우 약 1.3배, 검색의 경우에는 동일하게 4배정도 차이를 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헌데 코드를 잘 보시면 알겠지만 이는 삽입한 순서대로 검색하였을 때의 결과입니다. 역순으로 검색을 하였을때에는 아래와 같은 결과가 나옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxPKeV/btsBgdjDRPP/AU5tJJJZo62Yyy1nO81a7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxPKeV/btsBgdjDRPP/AU5tJJJZo62Yyy1nO81a7K/img.png&quot; data-origin-width=&quot;412&quot; data-origin-height=&quot;240&quot; data-is-animation=&quot;false&quot; style=&quot;width: 31.8724%; margin-right: 10px;&quot; data-widthpercent=&quot;32.63&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxPKeV/btsBgdjDRPP/AU5tJJJZo62Yyy1nO81a7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxPKeV%2FbtsBgdjDRPP%2FAU5tJJJZo62Yyy1nO81a7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;412&quot; height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KSp9y/btsBirafy38/mNrtT0upx17fNKu5K3a94K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KSp9y/btsBirafy38/mNrtT0upx17fNKu5K3a94K/img.png&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;232&quot; data-is-animation=&quot;false&quot; style=&quot;width: 30.8907%; margin-right: 10px;&quot; data-widthpercent=&quot;31.63&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KSp9y/btsBirafy38/mNrtT0upx17fNKu5K3a94K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKSp9y%2FbtsBirafy38%2FmNrtT0upx17fNKu5K3a94K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;386&quot; height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ujvyD/btsBiSZQpFD/HiBuoeTzTOv5seBTPcqGF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ujvyD/btsBiSZQpFD/HiBuoeTzTOv5seBTPcqGF1/img.png&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;234&quot; data-is-animation=&quot;false&quot; style=&quot;width: 34.9113%;&quot; data-widthpercent=&quot;35.74&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ujvyD/btsBiSZQpFD/HiBuoeTzTOv5seBTPcqGF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FujvyD%2FbtsBiSZQpFD%2FHiBuoeTzTOv5seBTPcqGF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;각각 숫자와 문자, 심볼을 역순으로 검색하였을 때 출력된 시간입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삽입 시간의 경우 변경된 것이 없지만 검색의 경우 문자와 심볼에서 Object가 Map에 비해 더 앞서는 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 실제로 빈번한 추가 및 제거에서는 Map이 확실히 앞서는 모습을 보여주었으나 검색은 경우에 따라 달라지는 것을 확인하였습니다. 다만 평균적으로 Map이 앞서는 것 같아 데이터를 다룰 때에는 Map을 사용하는 것이 더 좋아보입니다.&lt;/p&gt;</description>
      <category>Computer Science</category>
      <category>javascript</category>
      <category>map</category>
      <category>Object</category>
      <category>시간</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/122</guid>
      <comments>https://imygnam.tistory.com/122#entry122comment</comments>
      <pubDate>Sat, 2 Dec 2023 23:07:21 +0900</pubDate>
    </item>
    <item>
      <title>TCP ( Transmission Control Protocol )</title>
      <link>https://imygnam.tistory.com/121</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;TCP ( Transmission Control Protocol )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transmission : 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Control : 제어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Protocol : 프로토콜 ( 통신 규약 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OSI 7 Layer에서 Transport Layer ( 4계층 )을 사용하는 프로토콜로 3계층에서 사용하는 IP와 같이 묶어서 TCP/IP라고 많이 부릅니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;TCP란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 세그먼트 단위로 데이터 통신을 하기 위한 프로토콜이며 다음과 같은 특징을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 연결 지향적&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 통신을 시작하기 전에 &lt;b&gt;3-way handshake&lt;/b&gt; 방식으로 연결을 설정하고, 통신을 종료할때 &lt;b&gt;4-way handshake&lt;/b&gt; 방식으로 연결을 종료합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 신뢰성 있는 통신&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 데이터 세그먼트의 순서, 손실을 관리하여 데이터가 정확하게 수신되도록 통신합니다. 이것이 가능하도록 TCP는 각 세그먼트에 순서 번호를 할당하고 수신자는 받은 세그먼트에 대해 확인 응답(ACK)를 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 전이중, 점대점 통신&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 전이중 통신 ( 하나의 연결에 &lt;b&gt;송수신이 동시에 가능&lt;/b&gt; ) 이 가능하며, 점대점 방식 ( &lt;b&gt;하나의 연결은 정확히 2개의 종단점&lt;/b&gt;을 가짐 ) 으로 통신합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. 흐름 제어 ( Flow Control ) 과 혼잡 제어 ( Congestion Control ) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흐름 제어와 혼합 제어를 통해 &lt;b&gt;효율적인 데이터 전송&lt;/b&gt;을 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 방식들에 대해 좀 더 자세히 알아보면 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-way handshake&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SYN&lt;/b&gt; : Syncronize 의 약자로 &quot;동기화&quot;로 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ACK&lt;/b&gt; : Acknowledgment 의 약자로 &quot;승인&quot;으로 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명칭부터 3-way handshake이니 총 3번 통신이 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Client 측에서 Server 측에 &lt;b&gt;SYN 패킷&lt;/b&gt;을 보내는데 이때 &lt;b&gt;랜덤으로 생성한 Sequence Number&lt;/b&gt;를 담아 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Server 측은 수신한 Sequence Number에 1을 더하고 ACK 패킷을 Client에 보내는데 이때 SYN 또한 활성화 하여 보냅니다. 즉 &lt;b&gt;ACK + SYN 패킷&lt;/b&gt;을 수신한 &lt;b&gt;Sequence Number에 1을 더해&lt;/b&gt; 함께 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Client는 수신한 패킷의 Sequence Number가 자신이 보낸 것에 1 더해진 값이 맞는지 확인하고 정상이라면 Server에게 다시 &lt;b&gt;ACK 패킷&lt;/b&gt;을 보냅니다. 서버가 이를 수신하면 연결이 완료된 상태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-way handshake&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FIN&lt;/b&gt; : Finish의 약자로 &quot;끝&quot;으로 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3-way handshake와 마찬가지로 명칭이 4-way handshake이니 총 4번 통신이 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Client 측에서 통신을 종료하겠다는 의미인 &lt;b&gt;FIN 패킷&lt;/b&gt;을 Server 측에 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Server 측은 FIN 패킷을 수신하면 우선 알겠다는 의미로 &lt;b&gt;ACK 패킷&lt;/b&gt;을 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그 후 Server 측에서 FIN 패킷을 보내는데 만약 보낼 데이터가 남아 있다면 해당 데이터를 &lt;b&gt;전부 보낸 다음 FIN 패킷&lt;/b&gt;을 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Client 측은 FIN 패킷을 받으면 확인했다는 의미로 &lt;b&gt;ACK 패킷&lt;/b&gt;을 다시 Server 에 보냅니다. 이제 연결이 종료됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;연결 후 통신 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결이 성립된 후에는 이제 데이터를 주고 받아야합니다. 예를들어 Server 측에서 Client에게 데이터를 보낸다고 가정한다면 다음과 같은 과정을 거칩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;Application (Server) 이 데이터를 보내려고합니다. 해당 데이터를 보내기 위해 Socket Api 를 이용하여 Transport 계층으로 데이터를 내려보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Transport 계층 ( TCP ) 는 해당 데이터를 받아 쪼개서 Segment 단위로 만들고 번호를 붙입니다. 그후 각 Segment를 Network 계층으로 내려보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Network 계층은 받은 Segment 데이터를 Packet으로 변환하고 DataLink 계층으로 내려보내며 이때 Frame으로 변환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 해당 Frame은 Client까지 가게되고 Client는 해당 패킷을 받아 Transport 계층 ( TCP ) 까지 오게 됩니다. 올바른 Segment라면 Buffer에 담게 되고 잘 받았다고 Server에게 ACK를 해당 Segment 번호와 함께 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Server는 ACK를 받으면 다음 Segment를 전송합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;흐름 제어 ( Flow Control )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Sliding Window&lt;/b&gt; - 수신자가 처리할 수 있는 데이터의 양을 조절하여 Buffer Overflow를 방지하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정에서 4,5를 진행함에 있어 1개씩 전송하면 매우 비효율적일 것입니다. 특히 TCP가 느린 이유중 가장 큰 원인은 해당 Segment를 보내고 ACK를 받기까지 Wait하고 있기 때문입니다. 하여 TCP는 4번과정에서 여러 Segment를 한번에 보내는데 이를 가능하게 하려면 Client 측의 Buffer 크기를 알아야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client의 Buffer 보다 크게 보낸다면 Client는 해당 데이터를 전부 수신하지 못할 테고 이로인해 낭비가 크기 때문입니다. 따라서 &lt;b&gt;Client는 Server 측에 남은 Buffer 크기 즉 Window Size를 보내&lt;/b&gt;줍니다. 그 크기를 확인하고 서버는 해당 크기에 알맞게 데이터를 보내게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 Window Size는 3-way handshake를 하는 중에 바로 보내줍니다. 즉 처음 SYN 과정에서 보내줍니다. 그 다음부터는 4번과정인 Server에 ACK를 보낼때 함께 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Window Size가 확정된 후에는 각 Segment 를 보내고 ACK가 도착한다면 다음 패킷을 보내면 됩니다. 이것이 Window 가 점차 움직이는 것 처럼 보이기에 Sliding Window 라고 부릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;혼잡 제어 ( Congestion Control )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client가 수신할 수 있는 양과는 별개로 &lt;b&gt;네트워크가 데이터를 감당하지 못할 수&lt;/b&gt; 있습니다. 특정 라우터에 데이터가 몰릴 경우, 해당 데이터를 모두 처리 할 수 없고 이로 인해 재전송이 발생하는 등 혼잡도가 증가하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우를 해결하기위해 송신하는 쪽에서 데이터의 &lt;b&gt;전송속도를 조절&lt;/b&gt;하게 되는데 이 과정을 혼잡 제어라고 합니다. 혼잡 제어를 하는 방식은 여러가지가 있는데 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AIMD&lt;/b&gt; ( Additive Increase / Multiplicative Decrease )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해석하면 &quot;합 증가 / 곱 감소&quot;로 말 그대로 선형적으로 증가하다 절반으로 감소하는 형태입니다. 초기에 Client에게 보내는 &lt;b&gt;패킷 수를 1개씩 늘려&lt;/b&gt;가다가 전송이 실패하거나 일정시간 응답이 없다면 보내는 &lt;b&gt;패킷 수를 절반으로 감소&lt;/b&gt;하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식의 문제점은 초기부터 높은 전송 속도를 가질 수 없고, 네트워크가 혼잡해지고 나서야 대역폭이 줄기 때문에 혼잡해지는 상황을 미리 감지하지는 못한다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Slow Start&lt;/b&gt; ( 느린 시작 )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;느린 시작 방식은 AIMD 처럼 패킷을 초기에 1개씩 보내지만 성공적으로 ACK 가 수신된다면 &lt;b&gt;수신된 만큼 Window Size 를 증가&lt;/b&gt;시키는 방법입니다. 즉 처음에 1개를 보내고 ACK개 1개 수신된다면 그다음은 2개를 보내고 2개의 ACK가 수신된다면 다음 4개를 보내는 방식으로 AIMD의 방식과 다르게 &lt;b&gt;지수 함수 형태로 전송 속도가 증가&lt;/b&gt;하게 됩니다. 다만 전송 실패 시 ( Timeout ) AIMD 처럼 절반으로 떨어뜨리는 것이 아닌 &lt;b&gt;창의 크기를 1로 떨어뜨립&lt;/b&gt;니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Fast Recovery&lt;/b&gt; ( 빠른 회복 )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크에서 &lt;b&gt;패킷 손실이 감지되면 윈도우 크기를 1로 줄이는 것이 아닌 절반&lt;/b&gt;으로 줄이는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 &lt;b&gt;중복된 ACK&lt;/b&gt; 등 일부 패킷 손실 시에 &lt;b&gt;Fast Recovery 를 진행&lt;/b&gt;하며 &lt;b&gt;Timeout&lt;/b&gt; ( 타임아웃 )이 발생하면 &lt;b&gt;Window Size를 1로 변경&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACK 가 중복이 일어났다는 것은 도착해야할 패킷보다 이후의 패킷이 먼저 도착했다는 의미입니다. 예를들어 1,2,3,4 를 전송했는데 도중 3이 사라졌다면 Client는 ACK 2,3을 전송하고 4가 왔을때에도 ACK 3을 전송하게 됩니다. 타임아웃은 설정된 시간내에 어떠한 ACK도 오지 않았을 때 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Congestion Avoidance &lt;/b&gt;( 혼잡 회피 )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크의 혼잡을 감지하면 전송률 증가를 늦추고, 순차적으로 증가시킵니다 ( AIMD 방식 ). 즉 Slow Start 이후에 &lt;b&gt;특정 크기까지 전송 속도가 커진&lt;/b&gt;다면 이후로는 지수적으로 증가하는 것이 아닌 &lt;b&gt;선형적으로 증가&lt;/b&gt;하는 형태로 변경합니다. 이 특정 크기는 &lt;b&gt;ssthresh&lt;/b&gt; ( Slow Start Threshold ) 로 Slow Start와 Congestion Avoidance의 임계값이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Fast Retransmit &lt;/b&gt;( 빠른 재전송 )&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACK의 중복이 발생했다는 것은 해당 패킷이 손실되었다는 것을 의미합니다. Fast Retransmit은 &lt;b&gt;중복이 3번 반복 &lt;/b&gt;( default ) 되면 해당 패킷의 ACK를 Timeout 될때까지 기다리는 것이 아니라 &lt;b&gt;바로 재전송&lt;/b&gt;을 합니다. 물론 중복이 발생했기에 Fast Recovery 또한 진행됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 전체 혼잡 제어 기능을 살펴보면 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Slow Start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ssthresh 만큼 Window Size가 커진다면 그 이후로는 Congestion Avoidance.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 통신 도중 패킷 손실 등 ACK 중복 발생시 Fast Recovery 만약 3회 이상이라면 Fast Retransmit 진행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 통신 도중 TimeOut 발생시 Window Size 1로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science</category>
      <category>3-way handshake</category>
      <category>4-Way HandShake</category>
      <category>AIMD</category>
      <category>Congestion Avoidance</category>
      <category>Congestion Control</category>
      <category>fast recovery</category>
      <category>fast retransmit</category>
      <category>Flow Control</category>
      <category>Slow Start</category>
      <category>TCP</category>
      <author>imygnam</author>
      <guid isPermaLink="true">https://imygnam.tistory.com/121</guid>
      <comments>https://imygnam.tistory.com/121#entry121comment</comments>
      <pubDate>Fri, 1 Dec 2023 00:03:34 +0900</pubDate>
    </item>
  </channel>
</rss>