<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>신우섭의 도서관</title>
    <link>https://shinwusub.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 6 May 2026 23:01:50 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>신우섭</managingEditor>
    <image>
      <title>신우섭의 도서관</title>
      <url>https://tistory1.daumcdn.net/tistory/3330543/attach/5df91975d0014edb9afeb71f1ddc36b4</url>
      <link>https://shinwusub.tistory.com</link>
    </image>
    <item>
      <title>KOTITI 시험연구원 직원식당 점심 메뉴</title>
      <link>https://shinwusub.tistory.com/162</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: right;&quot;&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;2127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI0Jif/btsKF5H9o3p/jPGcz9TAasixyRtSEE0Kh0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI0Jif/btsKF5H9o3p/jPGcz9TAasixyRtSEE0Kh0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI0Jif/btsKF5H9o3p/jPGcz9TAasixyRtSEE0Kh0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI0Jif%2FbtsKF5H9o3p%2FjPGcz9TAasixyRtSEE0Kh0%2Fimg.jpg&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;1080&quot; height=&quot;2127&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;2127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;</description>
      <category>Temp</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/162</guid>
      <comments>https://shinwusub.tistory.com/162#entry162comment</comments>
      <pubDate>Tue, 12 Nov 2024 11:25:36 +0900</pubDate>
    </item>
    <item>
      <title>그림을 통한 좌표계(X, Y, Z) 및 회전방향(Pitch, Yaw, Roll) 외우기</title>
      <link>https://shinwusub.tistory.com/159</link>
      <description>&lt;h1&gt;X, Y, Z 좌표계&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kIgX5/btrzQHe1J8t/8ZblEIk4PGbZrIcnnVtN10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kIgX5/btrzQHe1J8t/8ZblEIk4PGbZrIcnnVtN10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kIgX5/btrzQHe1J8t/8ZblEIk4PGbZrIcnnVtN10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkIgX5%2FbtrzQHe1J8t%2F8ZblEIk4PGbZrIcnnVtN10%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;389&quot; height=&quot;507&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;회전 방향&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beULAU/btrzTe3J4FP/vuBK9wuYbONNiBcpwhjoOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beULAU/btrzTe3J4FP/vuBK9wuYbONNiBcpwhjoOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beULAU/btrzTe3J4FP/vuBK9wuYbONNiBcpwhjoOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeULAU%2FbtrzTe3J4FP%2FvuBK9wuYbONNiBcpwhjoOk%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;605&quot; height=&quot;474&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;FRotator&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLt7mf/btrzLHfPzrb/6YPkMbwFdM2UY2jLk5fD31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLt7mf/btrzLHfPzrb/6YPkMbwFdM2UY2jLk5fD31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLt7mf/btrzLHfPzrb/6YPkMbwFdM2UY2jLk5fD31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLt7mf%2FbtrzLHfPzrb%2F6YPkMbwFdM2UY2jLk5fD31%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;1024&quot; height=&quot;357&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.unrealengine.com/4.26/en-US/API/Runtime/Core/Math/FRotator/&quot;&gt;UE4 FRotator Document&lt;/a&gt;&lt;/p&gt;</description>
      <category>C++/Unreal Engine</category>
      <category>coordinate system</category>
      <category>rotator</category>
      <category>UE4</category>
      <category>UE5</category>
      <category>unrealengine</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/159</guid>
      <comments>https://shinwusub.tistory.com/159#entry159comment</comments>
      <pubDate>Tue, 19 Apr 2022 23:42:38 +0900</pubDate>
    </item>
    <item>
      <title>엘라스틱 서치 클러스터 내부 구조</title>
      <link>https://shinwusub.tistory.com/158</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1442&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTd1RJ/btrwZXkBl6b/WKhx6i9LTIqe2mvNA1ttPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTd1RJ/btrwZXkBl6b/WKhx6i9LTIqe2mvNA1ttPK/img.png&quot; data-alt=&quot;클러스터 내부 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTd1RJ/btrwZXkBl6b/WKhx6i9LTIqe2mvNA1ttPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTd1RJ%2FbtrwZXkBl6b%2FWKhx6i9LTIqe2mvNA1ttPK%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;1442&quot; height=&quot;868&quot; data-origin-width=&quot;1442&quot; data-origin-height=&quot;868&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;클러스터 내부 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프라이머리 샤드는 인덱스 생성 후 불변하다&lt;/li&gt;
&lt;li&gt;프라이머리 샤드는 클러스터링 된 노드에 분산 생성된다.(예: 전체 노드의 수가 3개 이고 Number_of_shards : 3 이면 각 노드별로 1개의 프라이머리 샤드가 생성) &lt;/li&gt;
&lt;li&gt;레플리카 샤드는 클러스티링 된 노드에 각각 생성된다. (예: 전체 노드의 수가 3개 이고 Number_of_replicas : 3 이면 각 노드별로 3개의 레플리카 샤드가생성)&lt;/li&gt;
&lt;li&gt;각 노드의 레플리카 샤드는 현재 노드에 생성되어있는 프라이머리 노드가 아닌 다른 노드의 프라이머리 노드를 복사한다&lt;/li&gt;
&lt;li&gt;클러스터링 된 노드의 다수가 다운되면 해당 클러스터는 정상 동작할 수 없다&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Elastic</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/158</guid>
      <comments>https://shinwusub.tistory.com/158#entry158comment</comments>
      <pubDate>Thu, 24 Mar 2022 10:38:16 +0900</pubDate>
    </item>
    <item>
      <title>대용량 데이터를 소규모의 Bulk로 너무 잘게 쪼개면 데이터 소실의 위험이 존재한다!</title>
      <link>https://shinwusub.tistory.com/157</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;패킷 사이즈 제한때문에 100만 Document를 insert하는 BulkInsert를 100개의 Document씩 잘개쪼개면 Elasticsearch write 풀의 대기큐 공간만 많이 잡아먹게된다.&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;너무 크면 elasticsearch내부에서 알아서 대용량 Bulk를 쪼개서 대기 큐에 적재하는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 너무 커서 패킷 사이즈를 초과하지 않고, 너무 작아서 write 대기큐의 공간을 많이 잡아먹지 않도록 쪼개는게 중요하다.&lt;/p&gt;</description>
      <category>Elastic</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/157</guid>
      <comments>https://shinwusub.tistory.com/157#entry157comment</comments>
      <pubDate>Wed, 23 Mar 2022 17:41:18 +0900</pubDate>
    </item>
    <item>
      <title>싱글톤(Spring Bean) 객체 사용 꼭!! 지켜야할 주의점!</title>
      <link>https://shinwusub.tistory.com/156</link>
      <description>&lt;h1&gt;무상태(stateless)로 설계해야 한다!&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;특정 클라이언트에 의존적인 필드가 있으면 안된다.&lt;/li&gt;
&lt;li&gt;특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.&lt;/li&gt;
&lt;li&gt;가급적 읽기만 가능해야 한다.&lt;/li&gt;
&lt;li&gt;필드 대신에 자바에서 &lt;strong&gt;공유되지 않는&lt;/strong&gt;, &lt;strong&gt;지역변수&lt;/strong&gt;, &lt;strong&gt;파라미터&lt;/strong&gt;, &lt;strong&gt;ThreadLocal&lt;/strong&gt; 등을 사용해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;왜?&lt;/h1&gt;
&lt;p&gt;싱글톤 객체는 단일 객체다(유일함) 이 객체가 내부에 변수를 가지고있고 쓰기를 허용한다면, 여기저기서 이 값을 막 바꾸게 된다.&lt;br&gt;내가 원하는 시점에 싱글톤 객체를 사용했는데 이 타이밍에 다른 녀석들이 똑같이 싱글톤 객체를 사용한다면 원하는 값이 나오지 않을 가능성이 높아진다.&lt;/p&gt;</description>
      <category>JAVA/Spring &amp;amp; Spring Boot</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/156</guid>
      <comments>https://shinwusub.tistory.com/156#entry156comment</comments>
      <pubDate>Mon, 14 Mar 2022 22:52:13 +0900</pubDate>
    </item>
    <item>
      <title>Elasticsearch 스냅샷 사용 방법 (링크)</title>
      <link>https://shinwusub.tistory.com/155</link>
      <description>&lt;h1&gt;공식문서가 너무 잘 설명되어있어서 별다른 포스팅없이 링크로 대체합니다.&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshots-take-snapshot.html&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshots-take-snapshot.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>Elastic</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/155</guid>
      <comments>https://shinwusub.tistory.com/155#entry155comment</comments>
      <pubDate>Mon, 14 Mar 2022 09:36:00 +0900</pubDate>
    </item>
    <item>
      <title>java 프로세스 메모리가 계속 증가한다..! 메모리 누수일까?</title>
      <link>https://shinwusub.tistory.com/154</link>
      <description>&lt;h1&gt;java 프로세스 메모리가 계속 증가한다..! 메모리 누수일까?&lt;/h1&gt;
&lt;p&gt;CentOS7에 java 프로세스를 가동시키고 해당 java service가 제공하는 api를 계속 호출했더니 메모리가 야금야금 증가해서 증가한 메모리를 유지하는 현상을 발견했습니다&lt;br&gt;과연 이게 메모리 누수인지 아니면 다른 이유인지 확인해 보겠습니다.&lt;/p&gt;
&lt;h2&gt;Java Service 실행 환경&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;api version : 2.3.1
os : CentOS Linux release 7.7.1908 (Core)
jdk : openjdk &amp;quot;14.0.1&amp;quot;
java options : -server -Xms2g -Xmx2g -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Java options 설명&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;server&lt;/strong&gt; : 해당 옵션은 최고 작동 속도를 최대화하도록 특별히 조정되었습니다. 빠른 시작 시간 또는 더 작은 런타임 메모리 풋 프린트보다 가능한 가장 빠른 작동 속도가 필요한 장기 실행 서버 애플리케이션을 실행하기위한 것입니다.&lt;br&gt;&lt;strong&gt;64bit JDK 는 암시적으로 무조건 server 옵션이 적용됩니다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xms&lt;/strong&gt; : 설정은 Java 힙의 초기 크기를 제어합니다. 이 매개변수를 적절하게 조정하면 가비지 콜렉션의 오버헤드를 줄여서 서버 응답 시간 및 처리량을 개선합니다. 일부 응용프로그램의 경우, 이 옵션에 대한 기본 설정이 너무 낮아서 사소한 가비지 콜렉션의 수가 높아질 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xmx&lt;/strong&gt; : Java 힙의 최대 크기를 제어합니다. 이 매개변수를 늘리면 Application Server에 사용 가능한 메모리가 늘어나고 가비지 콜렉션 빈도가 줄어듭니다. 이 설정을 늘리면 서버 응답 시간 및 처리량이 개선될 수 있습니다. 그러나 이 설정을 늘리면 가비지 콜렉션이 발생할 때 해당 콜렉션의 지속 기간이 늘어납니다. 이 설정은 Application Server 인스턴스에 대해 사용 가능한 시스템 메모리 이상으로 증가해서는 안됩니다. 설정을 사용 가능한 시스템 메모리 이상으로 늘리면 시스템 페이징 및 상당한 성능 감소를 유발할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xss&lt;/strong&gt; : 스레드 스택 크기(바이트)를 설정합니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-XX:MetaspaceSize&lt;/strong&gt; : 가비지 컬렉션을 처음 초과할 때 트리거할 할당된 클래스 메타데이터 공간의 크기를 설정합니다. 가비지 수집에 대한 이 임계값은 사용된 메타데이터 양에 따라 증가하거나 감소합니다. 기본 크기는 플랫폼에 따라 다릅니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;-XX:MaxMetaspaceSize&lt;/strong&gt; : 클래스 메타데이터에 할당할 수 있는 최대 네이티브 메모리 양을 설정합니다. 기본적으로 크기는 제한되지 않습니다. 응용 프로그램의 메타데이터 양은 응용 프로그램 자체, 실행 중인 다른 응용 프로그램 및 시스템에서 사용할 수 있는 메모리 양에 따라 달라집니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;oracle options doc : &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html&quot;&gt;https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html&lt;/a&gt;&lt;/p&gt;
&lt;/br&gt;

&lt;h2&gt;분석&lt;/h2&gt;
&lt;hr&gt;
&lt;h3&gt;코딩 실수로인한 메모리 누수(Memory leak) 여부&lt;/h3&gt;
&lt;p&gt;코딩상의 실수로 메모리가 누수가 발생하였는지 판단합니다.&lt;/p&gt;
&lt;h4&gt;1. Eclipse Memory Analyzer를 이용한 Heap Dump 분석&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;2.4gb&lt;/strong&gt; 로 동작중이던 Java process의 memory가 &lt;strong&gt;2.6gb&lt;/strong&gt;로 증가되고 유지되었습니다.&lt;br&gt;증가량은 약 &lt;strong&gt;0.2gb&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;p&gt;메모리 누수 여부를 확인하기 위하여 &lt;strong&gt;jmap&lt;/strong&gt;으로 증가한 java service의 &lt;strong&gt;Heap Dump&lt;/strong&gt;를 가져와 &lt;strong&gt;Eclipse Memory Analyzer&lt;/strong&gt; 로 분석합니다.&lt;/p&gt;
&lt;h4&gt;jmap 을 이용한 heap dump 생성 방법&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./jmap -dump:format=b,file=&amp;lt;파일명&amp;gt; &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;분석 결과&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsZl11/btrvPfzCvpT/RJamKnrISf4ENZkb9fKDK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsZl11/btrvPfzCvpT/RJamKnrISf4ENZkb9fKDK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsZl11/btrvPfzCvpT/RJamKnrISf4ENZkb9fKDK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsZl11%2FbtrvPfzCvpT%2FRJamKnrISf4ENZkb9fKDK0%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;해당 service의 dump를 확인 결과 현재 사용중인 heap memory 영역은 &lt;strong&gt;43.3mb&lt;/strong&gt;이며 메모리 증가로 가정되었던 &lt;strong&gt;0.2gb&lt;/strong&gt;에 현저히 미치지 못하는 사용률을 보입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;/br&gt;

&lt;h4&gt;2. Jconsole 을 이용한 실시간 Heap Memory 모니터링&lt;/h4&gt;
&lt;p&gt;위 Dump를 근거로 실제 Heap Memory사용이 비슷하게 이루어지나 실시간 모니터링을 실시합니다.&lt;/p&gt;
&lt;h4&gt;Jconsole 사용 방법&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;감시하고싶은 java process를 시작할때 아래와 같은 &lt;strong&gt;java options&lt;/strong&gt; 을 추가한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=임의의 PORT
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=서비스할 PC IP&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;모니터링을 진행할 PC에서 Jconsole을 실행합니다.&lt;/li&gt;
&lt;li&gt;실행 된 Jconsole에서 Remote Process에 위에서 지정한 &lt;strong&gt;-Djava.rmi.server.hostname&lt;/strong&gt;의 값을 넣어 연결합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;분석 결과&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oRr4L/btrvLIC3GJD/L9eQdls9nToKhsub0wzh2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oRr4L/btrvLIC3GJD/L9eQdls9nToKhsub0wzh2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oRr4L/btrvLIC3GJD/L9eQdls9nToKhsub0wzh2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoRr4L%2FbtrvLIC3GJD%2FL9eQdls9nToKhsub0wzh2k%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p7555/btrvPe8zdnj/P9ku7YKeEZy4qf8iPEbJkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p7555/btrvPe8zdnj/P9ku7YKeEZy4qf8iPEbJkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p7555/btrvPe8zdnj/P9ku7YKeEZy4qf8iPEbJkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp7555%2FbtrvPe8zdnj%2FP9ku7YKeEZy4qf8iPEbJkk%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 이미지를 통하여 &lt;strong&gt;Heap memory&lt;/strong&gt;는 java prcess를 실행할때 지정했던 option &lt;strong&gt;Xmx2g&lt;/strong&gt; 를 상회하지 않고 &lt;strong&gt;할당&lt;/strong&gt;과 &lt;strong&gt;해제&lt;/strong&gt;가 뚜렷하게 보이며 위 그래프를 통해 &lt;strong&gt;Heap memory&lt;/strong&gt; 즉 개발자가 &lt;strong&gt;임의적으로 할당하는 메모리 영역&lt;/strong&gt;에 대한 누수는 확인되지 않았습니다.&lt;/p&gt;
&lt;/br&gt;

&lt;h4&gt;메모리 누수가 발생하는 Java Process의 예시&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnNgzs/btrvRzxB6XI/K3L6rXStUWYdjUHSk64jc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnNgzs/btrvRzxB6XI/K3L6rXStUWYdjUHSk64jc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnNgzs/btrvRzxB6XI/K3L6rXStUWYdjUHSk64jc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnNgzs%2FbtrvRzxB6XI%2FK3L6rXStUWYdjUHSk64jc1%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhFaOB/btrvQgSyY8B/Ye4miKuCnU8DKo96rh7yc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhFaOB/btrvQgSyY8B/Ye4miKuCnU8DKo96rh7yc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhFaOB/btrvQgSyY8B/Ye4miKuCnU8DKo96rh7yc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhFaOB%2FbtrvQgSyY8B%2FYe4miKuCnU8DKo96rh7yc1%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;결론&lt;/h1&gt;
&lt;h3&gt;그렇다면 메모리 누수가 아닌대 오르고있는 메모리는 무엇인가?&lt;/h3&gt;
&lt;p&gt;메모리 누수가 아니다, 그렇다면 실제로 오르고있는 저 메모리는 무엇일까요?&lt;br&gt;java 프로세스의 메모리 영역은 크게 &lt;strong&gt;Heap Memory&lt;/strong&gt; 와 &lt;strong&gt;Native Memory&lt;/strong&gt; 영역이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kK7gi/btrvPfzCCC9/Q5zu2UdzDm2lUXkfB07FE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kK7gi/btrvPfzCCC9/Q5zu2UdzDm2lUXkfB07FE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kK7gi/btrvPfzCCC9/Q5zu2UdzDm2lUXkfB07FE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkK7gi%2FbtrvPfzCCC9%2FQ5zu2UdzDm2lUXkfB07FE0%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 그림과 같이 영역 구분이 가능하며 이중에서 사용자가 크기를 설정할 수 있는 부분은 &lt;strong&gt;Java Heap&lt;/strong&gt;과 &lt;strong&gt;Metaspace&lt;/strong&gt; 영역입니다.&lt;br&gt;그 외 영역은 JVM과 OS가 사용하는 영역이며 최대 사용량에 대한 예측은 &lt;strong&gt;JVM native memory tracking&lt;/strong&gt; 으로 JVM이 임시로 잡아두는 영역인 &lt;strong&gt;reserved(임시 메모리)&lt;/strong&gt; 값을 통하여 확인가능합니다.&lt;/p&gt;
&lt;h4&gt;JVM의 reserved 와 committed 의 예&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UhBph/btrvJ0iQWr5/JQcCX92xGpq23MWaaZQcyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UhBph/btrvJ0iQWr5/JQcCX92xGpq23MWaaZQcyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UhBph/btrvJ0iQWr5/JQcCX92xGpq23MWaaZQcyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUhBph%2FbtrvJ0iQWr5%2FJQcCX92xGpq23MWaaZQcyK%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;메모리 누수처럼 보이던 java service의 메모리 사용량이 증가하는 것은 JVM이 사용하는 &lt;strong&gt;Native Memory&lt;/strong&gt;의 &lt;strong&gt;committed(실제 사용중인 메모리)&lt;/strong&gt; 가 &lt;strong&gt;reserved(임시 메모리)&lt;/strong&gt; 크기 안에서 증가하는 것이며, 최대 &lt;strong&gt;reserved(임시 메모리)&lt;/strong&gt; 크기를 벗어나지 않을 것 입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;/br&gt;

&lt;h1&gt;기타 설명&lt;/h1&gt;
&lt;h4&gt;Heap Memory&lt;/h4&gt;
&lt;p&gt;힙 영역은 모든 자바 클래스의 인스턴스(instance)와 배열(array)이 할당되는 곳으로, 런타임(run time) 데이터를 저장하는 영역이다. 힙 영역은 JVM이 시작될 때 생성되어 애플리케이션이 실행되는 동안 크기가 커졌다 작아졌다 한다. 힙 영역의 크기는 -Xms VM option으로 지정된다고 한다. 힙 영역의 크기는 가비지 컬렉션의 전략에 따라 고정된 크기일수도 있고, 유동적으로 변경될 수도 있다.&lt;br&gt;oracle heap-memory doc : &lt;a href=&quot;https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html&quot;&gt;https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Native Memory&lt;/h4&gt;
&lt;p&gt;JVM은 클래스 메타데이터, 애플리케이션 코드, JIT에 의해 생성된 코드, 내부 데이터 구조 등을 유지하기 위해 네이티브 메모리에서 상당히 큰 청크를 할당합니다&lt;br&gt;JVM이 Native Memory 영역에 사용하는 항목들은 아래와 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metaspace&lt;/li&gt;
&lt;li&gt;Threads&lt;/li&gt;
&lt;li&gt;Code Cache&lt;/li&gt;
&lt;li&gt;Garbage Collection&lt;/li&gt;
&lt;li&gt;Symbols&lt;/li&gt;
&lt;li&gt;Native Byte Buffers&lt;/li&gt;
&lt;li&gt;Additional Tuning Flags&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;jvm native-memory doc : &lt;a href=&quot;https://www.baeldung.com/native-memory-tracking-in-jvm&quot;&gt;https://www.baeldung.com/native-memory-tracking-in-jvm&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;JVM native memory tracking 방법&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;java 실행인자에 -XX:NativeMemoryTracking=detail&lt;/li&gt;
&lt;li&gt;터미널 명령어 &amp;lt;jdk설치위치&amp;gt;/bin/jcmd &amp;lt;pid&amp;gt; VM.native_memory detail 실행&lt;/li&gt;
&lt;li&gt;결과&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;5746:

Native Memory Tracking:


Total: reserved=2914585KB, committed=2390505KB
-                 Java Heap (reserved=2097152KB, committed=2097152KB)
                            (mmap: reserved=2097152KB, committed=2097152KB)

-                     Class (reserved=315585KB, committed=68929KB)
                            (classes #12549)
                            (  instance classes #11710, array classes #839)
                            (malloc=2241KB #37324)
                            (mmap: reserved=313344KB, committed=66688KB)
                            (  Metadata:   )
                            (    reserved=59392KB, committed=58624KB)
                            (    used=57333KB)
                            (    free=1291KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=253952KB, committed=8064KB)
                            (    used=7290KB)
                            (    free=774KB)
                            (    waste=0KB =0.00%)

-                    Thread (reserved=85475KB, committed=31611KB)
                            (thread #294)
                            (stack: reserved=84088KB, committed=30224KB)
                            (malloc=1045KB #1766)
                            (arena=343KB #586)

-                      Code (reserved=249522KB, committed=25962KB)
                            (malloc=1834KB #9033)
                            (mmap: reserved=247688KB, committed=24128KB)

-                        GC (reserved=122444KB, committed=122444KB)
                            (malloc=11576KB #25778)
                            (mmap: reserved=110868KB, committed=110868KB)

-                  Compiler (reserved=513KB, committed=513KB)
                            (malloc=348KB #916)
                            (arena=165KB #5)

-                  Internal (reserved=4879KB, committed=4879KB)
                            (malloc=4843KB #4118)
                            (mmap: reserved=36KB, committed=36KB)

-                     Other (reserved=4735KB, committed=4735KB)
                            (malloc=4735KB #53)

-                    Symbol (reserved=11979KB, committed=11979KB)
                            (malloc=10756KB #310319)
                            (arena=1223KB #1)

-    Native Memory Tracking (reserved=6634KB, committed=6634KB)
                            (malloc=353KB #4976)
                            (tracking overhead=6282KB)

-        Shared class space (reserved=11324KB, committed=11324KB)
                            (mmap: reserved=11324KB, committed=11324KB)

-               Arena Chunk (reserved=3384KB, committed=3384KB)
                            (malloc=3384KB)

-                   Logging (reserved=5KB, committed=5KB)
                            (malloc=5KB #198)

-                 Arguments (reserved=14KB, committed=14KB)
                            (malloc=14KB #454)

-                    Module (reserved=508KB, committed=508KB)
                            (malloc=508KB #3665)

-                 Safepoint (reserved=8KB, committed=8KB)
                            (mmap: reserved=8KB, committed=8KB)

-           Synchronization (reserved=423KB, committed=423KB)
                            (malloc=423KB #2695)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/154</guid>
      <comments>https://shinwusub.tistory.com/154#entry154comment</comments>
      <pubDate>Sun, 13 Mar 2022 15:34:00 +0900</pubDate>
    </item>
    <item>
      <title>StackOverFlow 연속 질문 불가</title>
      <link>https://shinwusub.tistory.com/153</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;StackOverFlow 질문을 게시하고 바로 이어서 다른 질문을 올리려했는데 딱히 에러팝업도 안뜨고 질문이 게시되지 않는 현상이 있습니다.&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;Response를 확인해보니&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CBGZo/btru8URaPP6/8pWzoixdK7wEvzRnuxSk8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CBGZo/btru8URaPP6/8pWzoixdK7wEvzRnuxSk8k/img.png&quot; data-alt=&quot;연속 질문 불가!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CBGZo/btru8URaPP6/8pWzoixdK7wEvzRnuxSk8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCBGZo%2Fbtru8URaPP6%2F8pWzoixdK7wEvzRnuxSk8k%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;671&quot; height=&quot;128&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;128&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;&quot;You can only post once every 90 minutes&quot; 라는 메세지가 반환되네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;90분... 텀이 너무 긴거 아닙니까ㅠ&lt;/p&gt;</description>
      <category>Temp</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/153</guid>
      <comments>https://shinwusub.tistory.com/153#entry153comment</comments>
      <pubDate>Sat, 5 Mar 2022 23:05:39 +0900</pubDate>
    </item>
    <item>
      <title>추상화 된 빈 설정 메타 정보 BeanDefinition(빈 정의)</title>
      <link>https://shinwusub.tistory.com/151</link>
      <description>&lt;h1&gt;추상화 된 빈 설정 메타 정보 BeanDefinition(빈 정의)&lt;/h1&gt;
&lt;p&gt;스프링 XML, JAVA 코드, Groovy 등의 다양한 설정 형식을 지원합니다.&lt;br&gt;이렇게 다양한 설정을 지원할 수 있는 이유는 &lt;strong&gt;&amp;quot;BeanDefinition&amp;quot;&lt;/strong&gt; 이라는 추상화가 있기에 가능합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XML을 읽어서 -&amp;gt; BeanDefinition&lt;/li&gt;
&lt;li&gt;자바 코드를 읽어서 -&amp;gt; BeanDefinition&lt;/li&gt;
&lt;li&gt;Groovy 코드를 읽어서 -&amp;gt; BeanDefinition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;스프링 컨테이너는 JAVA 코드인지, XML인지 몰라도 됩니다, 오직 &lt;strong&gt;BeanDefintion&lt;/strong&gt; 만 알면 됩니다.&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diXcwu/btrslWxjdWQ/La2ma2fmizjssrfPyROEx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diXcwu/btrslWxjdWQ/La2ma2fmizjssrfPyROEx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diXcwu/btrslWxjdWQ/La2ma2fmizjssrfPyROEx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiXcwu%2FbtrslWxjdWQ%2FLa2ma2fmizjssrfPyROEx0%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;스프링 컨테이너는 이 &lt;strong&gt;BeanDefintion&lt;/strong&gt; 즉 빈 설정 메타정보를 기반으로 스프링 빈을 생성합니다.&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpTkuT/btrsqB6Rurp/eCMUIG9PwySnZ3U8P8asUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpTkuT/btrsqB6Rurp/eCMUIG9PwySnZ3U8P8asUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpTkuT/btrsqB6Rurp/eCMUIG9PwySnZ3U8P8asUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpTkuT%2FbtrsqB6Rurp%2FeCMUIG9PwySnZ3U8P8asUK%2Fimg.png&quot; width=&quot;100%&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>JAVA/Spring &amp;amp; Spring Boot</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/151</guid>
      <comments>https://shinwusub.tistory.com/151#entry151comment</comments>
      <pubDate>Fri, 4 Feb 2022 01:34:23 +0900</pubDate>
    </item>
    <item>
      <title>추상 구문 트리(abstract syntax tree, AST)란?</title>
      <link>https://shinwusub.tistory.com/150</link>
      <description>&lt;p&gt;java로 elasticsearch를 사용하는 중 쿼리 만들기가 너무 빡세(?) 룸북의 @Getter @Setter 어노테이션과 같이 컴파일 타임에서 자동으로 쿼리를 만들어주는 라이브러리를 만들어보려고 조사하다보니 AST라는 생소한 단어를 접하게되어 이것이 무엇인지 찾아 보았습니다.&lt;/p&gt;
&lt;h1&gt;추상 구문 트리(abstract syntax tree)&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;추상 구문 트리(abstract syntax tree)&lt;/strong&gt; 줄여서 &lt;strong&gt;AST&lt;/strong&gt; 라고 쉽게 부르며,&lt;br&gt;java에서만 볼 수 있는 용어가 아닌 컴파일러가 필요한 프로그래밍 언어라면 들을 수 있는 용어입니다&lt;/p&gt;
&lt;h2&gt;컴파일러와의 관계&lt;/h2&gt;
&lt;p&gt;컴파일러가 필요한 언어에서 AST를 접할 수 있는 이유는 AST가 컴파일 단계 중 &lt;strong&gt;구문 분석(syntax analyzing)&lt;/strong&gt; 단계의 결과물이기 때문입니다.&lt;/p&gt;
&lt;h4&gt;컴파일 단계&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;1. 어휘 분석(lexical analyze) or 스캔(scan)
2. 구문 분석(syntax analyzung) - 결과물로 구문트리(syntax tree) 또는 추상 구문 트리(abstract syntax tree)가 생성됨!
3. 의미 분석(semantic analysis)
4. 중간 표현의 생성(intermediate representation)
5. 코드 생성(code generation)
6. 최적화(optimization)
7. 어셈블러&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;본문에서는 편의를 위하여 AST라 부르겠습니다.&lt;/p&gt;
&lt;p&gt;AST는 프로그래밍 언어로 작성된 소스 코드의 추상 구문 구조의 트리이며, 이 트리의 각 노드는 소스코드에서 발생되는 구조를 나타냅니다.&lt;/p&gt;
&lt;p&gt;쉽게 말하면 우리가 작성한 &lt;strong&gt;소스코드를 문법에 맞게 노드들로 쪼개서 만든 트리&lt;/strong&gt;라고 생각하면됩니다.&lt;/p&gt;
&lt;h2&gt;추상(abstract) 인 이유?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;추상&lt;/strong&gt; 이라는 용어가 쓰인 이유는 이해하기 어렵거나 추상적 인 형태를 가지기 때문에가 아니라 코드에 필연적으로 나타나는 &lt;strong&gt;괄호&lt;/strong&gt; 및 &lt;strong&gt;기타 기호&lt;/strong&gt;와 같은 코딩 구문을 포함하지 않기 때문에 &lt;strong&gt;추상&lt;/strong&gt;이라고합니다.&lt;/p&gt;</description>
      <category>JAVA</category>
      <author>신우섭</author>
      <guid isPermaLink="true">https://shinwusub.tistory.com/150</guid>
      <comments>https://shinwusub.tistory.com/150#entry150comment</comments>
      <pubDate>Wed, 2 Feb 2022 20:58:57 +0900</pubDate>
    </item>
  </channel>
</rss>