<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_isaac.log</title>
        <link>https://velog.io/</link>
        <description>어려운 것은 쉽게, 쉬운 것은 기억에 남게.</description>
        <lastBuildDate>Fri, 08 Jan 2021 08:59:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_isaac.log</title>
            <url>https://images.velog.io/images/dev_isaac/profile/63d6047c-ff3b-4393-87ce-80df7afd1efc/KakaoTalk_20201227_001839185.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_isaac.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_isaac" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Fork/Join을 이용한 스레드 연산(작성중)]]></title>
            <link>https://velog.io/@dev_isaac/ForkJoin%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%8A%A4%EB%A0%88%EB%93%9C-%EC%97%B0%EC%82%B0%EC%9E%91%EC%84%B1%EC%A4%91</link>
            <guid>https://velog.io/@dev_isaac/ForkJoin%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%8A%A4%EB%A0%88%EB%93%9C-%EC%97%B0%EC%82%B0%EC%9E%91%EC%84%B1%EC%A4%91</guid>
            <pubDate>Fri, 08 Jan 2021 08:59:17 GMT</pubDate>
            <description><![CDATA[<p>자바 프로그램을 실행하면 하나의 프로세스가 동작하고, 그 프로세스는 하나 이상의 스레드로 이루어진다. 이 스레드를 더욱 효율적으로 사용하기 위한 클래스를 소개해 보겠다. 그 시작은 Fork/Join을 이해하는 것이다. </p>
<h3 id="fork나누고join모으고">Fork(나누고)/Join(모으고)</h3>
<blockquote>
<p>Fork는 여러 개를 나누는 작업을 말하고, Join은 작업 결과를 모으는 것이라고 생각하면 된다.   </p>
</blockquote>
<p>여기서 나아가 Work Stealing이라는 개념도 들어가는데, </p>
<h4 id="work-stealing">Work Stealing</h4>
<blockquote>
<p>여러 개의 Dequeue에 작업이 나뉘어져 어떤 일이 진행될 때 만약 하나의 Dequeue는 바쁘고, 다른 Dequeue는 바쁘지 않을 때가 있다. 이럴 경우 할 일이 없는 Dequeue가 바쁜 Dequeue에 대기하고 있는 일을 가져가서 해 주는 것이라고 생각하면 된다. 
(※참고 : 입구와 출구가 정해져 있는 Queue와는 달리, Dequeue는 양쪽 끝이 모두 입구와 출구가 되는 구조이다.)</p>
</blockquote>
<p>이같은 Work Stealing이 Fork/Join에 기본적으로 포함돼 있다. </p>
<p>기본적인 수행 개념은 다음과 같다.</p>
<pre><code>if(작업 단위가 충분히 작을 경우){
    해당작업 수행
}else{
    작업을 반으로 쪼개어 두 개 작업으로 나눔.
    두 작업을 동시에 실행, 두 작업 끝날 때까지 결과를 기다림
}</code></pre><p>보통 이 연산은 회귀적(Recursive)으로 수행된다. </p>
<h3 id="forkjoin을-사용하는-클래스">Fork/Join을 사용하는 클래스</h3>
<p>ForkJoinPool을 사용하려면 기본적으로 알아야 할 클래스들이 있다.</p>
<ul>
<li><p>ForkJoinPool</p>
<ul>
<li>fork-join방식으로 타스크를 생성하고 동작시키는 ForkJoin Framework의 모체</li>
</ul>
</li>
<li><p>RecursiveTask<V></p>
<ul>
<li>실제 작업의 단위가 되는 클래스는 이 클래스를 상속해야 한다. 또한 compute메소드에서 결과값을 리턴해야 한다.</li>
</ul>
</li>
<li><p>RecursiveAction</p>
<ul>
<li>RecursiveTask과 같은 용도로서, 작업의 단위가 되는 클래스가 상속해야 하는 클래스이다. 결과는 리턴하지 않는다.</li>
</ul>
</li>
<li><p>ForkJoinTask<V></p>
<ul>
<li>RecursiveTask의 부모클래스스로서 fork와 join메소드가 정의되어있다. 직접적으로 사용하지는 않는다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java7에서 변경된 것들]]></title>
            <link>https://velog.io/@dev_isaac/java7%EC%97%90%EC%84%9C-%EB%B3%80%EA%B2%BD%EB%90%9C-%EA%B2%83%EB%93%A4</link>
            <guid>https://velog.io/@dev_isaac/java7%EC%97%90%EC%84%9C-%EB%B3%80%EA%B2%BD%EB%90%9C-%EA%B2%83%EB%93%A4</guid>
            <pubDate>Thu, 07 Jan 2021 08:17:35 GMT</pubDate>
            <description><![CDATA[<p>초기버전의 java를 쭉 사용해 왔다면, 하나하나 기능이 추가될 때마다 그 유용함과 편리함을 몸소 체험했겠지만, 그동안 개발을 하면서 사용한 버전이 6이나 7이 대부분이었다보니 그럴 일이 없었던 것 같다.
그런 의미에서 java7에 오면서 새롭게 추가되거나 변경된 사항들에 대해서 살펴보려 한다. </p>
<h2 id="java7에서-변경된-것들">java7에서 변경된 것들</h2>
<h3 id="숫자-표시-방법-보완">숫자 표시 방법 보완</h3>
<ul>
<li>이전 버전까지는 0을 앞에 넣으면 8진수, 0x를 앞에 넣으면 16진수로 인식하는 것이 가능했다. java7부터는 아무 접두사가 없는 숫자는 10진수, 0b를 앞에 넣으면 2진수로 인식하는 것이 추가됐다.</li>
<li>_를 사용하여 숫자의 단위를 잘라서 표현할 수 있다. 가독성이 좋아졌다. <h3 id="switch문에서-string-사용">switch문에서 String 사용</h3>
</li>
<li>java6까지는 switch-case에서 정수형만 사용가능했었다. 7부터 String도 사용이 가능하다. </li>
</ul>
<h3 id="제네릭을-쉽게-사용할-수-있는-diamond">제네릭을 쉽게 사용할 수 있는 Diamond</h3>
<ul>
<li>기존에는 제네릭 사용 시에 &lt;&gt;안에 타입을 입력했어야 했다. 7부터는 그럴 필요가 없다. 왜냐하면 이미 변수 선언부에서 타입을 지정해놨기 때문이다. </li>
</ul>
<h3 id="예외가-보완되었다1">예외가 보완되었다.(1)</h3>
<p>이전까지는 예외처리르 ㄹ위해 try-catch문장을 사용했다. 이 부분에서 catch로 잡아주는 코드의 가독성이 떨어졌다. </p>
<pre><code>    public void scanFile(String fileName, String encoding){
        Scanner scanner = null;
        try{
            scanner = new Scanner(new File(fileName), encoding);
            System.out.println(scanner.nextLine());
        }catch(IllegalAccessException iae){
            iae.printStackTrace();
        }catch(FileNotFoundException ffe){
            ffe.printStackTrace();
        }catch(NullPointerException npe){
            npe.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(scanner != null){
            scanner.close();
            }
        }
    }</code></pre><p>위의 예시를 보면 파일명이 한글일 경우 타입명시를 해줘야 한다. 인코딩 타입이 존재하지 않을 경우에, IllegalArgumentException이 발생할 것이고, 파일이 존재하지 않을 경우에는 FileNotFoundException이 발생할 것이다. 파일명이나 인코딩 타입이 NullPointerException이 발생할 수 있다. 
지금까지는 일일이 발생할 만한 case에 맞춰서 catch블록을 만들어 처리하고, 마지막에 Exception 클래스로 catch해주는 것이 일반적이었다. </p>
<p>그러나 이제 java7부터는 다음과 같이 처리할 수 있다.</p>
<pre><code>    public void newScanFile(String fileName, String encoding){
        Scanner scanner = null;
        try{
            scanner = new Scanner(new File(fileName), encoding);
            System.out.println(scanner.nextLine());
        }catch(IllegalArgumentException | FileNotFoundException | NullPointerException exception){
            exception.printStackTrace();
        }finally{
            if(scanner != null){
            scanner.close();
            }
        }    
    }</code></pre><h3 id="예외가-보완되었다2">예외가 보완되었다.(2)</h3>
<p>try-with-resource(리소스와 함께 처리하는 try문장)이다.
아래 예시를 보자. </p>
<pre><code>
  public void newScanFileTryWithResource(String fileName, String encoding){
      try(Scanner scanner = new Scanner(new File(fileName), encoding)){
          System.out.println(scanner.nextLine());
      }catch(IllegalArgumentException | FileNotFoundException | NullPointerException exception){
      exception.printStackTrace();
      }    
  }</code></pre><p>이 구문의 특징은 다음과 같다.</p>
<ul>
<li>try의 소괄호 내에서 예외가 발생할 수 있는 객체에서, close()를 이용해 닫아야할 필요가 있을 때, AutoCloseable을 구현한 객체는 finally문장에서 별도로 처리할 필요가 없다는 것을 볼 수 있다. (AutoCloseable에 대해서는 아래에서 이어 말하겠다. )</li>
</ul>
<h3 id="autocloseable">AutoCloseable</h3>
<p>java5부터 추가된 java.io.Closeable인터페이스를 구현한 클래스들은 명시적으로 close()메소드를 사용하여 닫아줘야했지만, 
java7에 추가된 AutoCloseable 인터페이스를 상속한 클래스들은 앞서 살펴본 try-with-resource구문을 사용할 수 있다. 
AutoCloseable을 상속한 클래스들은 아래와 같다. (이외에도 많다.)</p>
<ul>
<li>java.nio.channels.FileLock</li>
<li>java.beans.XMLEncoder</li>
<li>java.beans.XMLDecoder</li>
<li>java.io.ObjectInput</li>
<li>java.io.ObjectOutput</li>
<li>java.util.Scanner</li>
<li>java.sql.Connection</li>
<li>java.sql.ResultSet</li>
<li>java.sql.Statement</li>
</ul>
<blockquote>
<p>출처 : 자바의 신(이상민 저)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java8에 추가된 것들]]></title>
            <link>https://velog.io/@dev_isaac/Java8%EC%97%90-%EC%B6%94%EA%B0%80%EB%90%9C-%EA%B2%83%EB%93%A4</link>
            <guid>https://velog.io/@dev_isaac/Java8%EC%97%90-%EC%B6%94%EA%B0%80%EB%90%9C-%EA%B2%83%EB%93%A4</guid>
            <pubDate>Mon, 04 Jan 2021 07:48:18 GMT</pubDate>
            <description><![CDATA[<p>Java8에 추가된 것들에 대해 아~~주 간략히 키워드만 살펴보자!</p>
<h2 id="optional">Optional</h2>
<blockquote>
<ul>
<li>null인 객체를 처리하기 위한 클래스</li>
</ul>
</blockquote>
<h2 id="default-메소드">default 메소드</h2>
<ul>
<li>원래 interface를 구현하는 클래스에서는 interface에 있는 메소드를 모두 구현하여야 컴파일 오류가 발생하지 않는다.  </li>
<li>이와는 다르게 default를 사용하여 interface에 선언한 메소드는 필수가 아닌 선택적으로 구현여부를 정할 수 있다. </li>
<li>이렇게 만든 이유는 과거에 만든 소스가 많은 개발자들에게 사용되는 상황에서 기존의 interface에 새로운 메소드를 추가해야하는 상황이
발생했기 때문이다. 기능 추가는 가능하되 컴파일 에러를 피할 수 있다. </li>
</ul>
<h2 id="lambda">Lambda</h2>
<ul>
<li>익명클래스 대용으로 사용하기 위해 만들어짐. 
=&gt; 익명클래스는 뭔가? 클래스 상속이나 인터페이스 구현을 위한 클래스를 생성하지 않고도 , 단일 객체를 만들어서 상속하려는 클래스나 구현하려는 인터페이스에 정의된 동작에 행위를 추가할 수 있게 하는 클래스이다. </li>
<li>lambda는 메소드가 하나만 선언된 인터페이스에 대해서만 사용할 수 있다.</li>
<li>2개 이상 선언되면 컴파일 오류가 발생하는데, 이것을 방지하기 위해 @FunctionalInterface라는 어노테이션을 제공한다. </li>
</ul>
<h2 id="javautilfunction-패키지">java.util.function 패키지</h2>
<ul>
<li>predicate, Supplier, Consumer, Function, UnaryOperator, BinaryOperator</li>
</ul>
<h2 id="stream">Stream</h2>
<ul>
<li>연속된 정보를 처리하는 데 사용한다. </li>
<li>기존에는 배열이나 컬렉션을 통해 연속된 정보를 사용해 왔다. </li>
</ul>
<p>스트림은 아래와 같은 기본구조를 가진다. </p>
<h3 id="liststreamfilterx--x10count">list.stream().filter(x-&gt; x&gt;10).count()</h3>
<ul>
<li>.stream()  : 스트림을 생성한다. </li>
<li>.fileter() : 중개연산을 한다. 리턴값이 없다. </li>
<li>.count() : 종단 연산을 한다. 중개연산 작업 후에 마지막 종단연산 하고 리턴한다. </li>
</ul>
<p>스트림에서 제공하는 연산의 종류는 많다. 그중에서 많이 사용하는 것들은
.filter(), map(), forEach()정도가 있겠다.</p>
<h3 id="stream-foreach는-주어진-객체에서-루프를-돌면서-명령을-수행한다">stream forEach()는 주어진 객체에서 루프를 돌면서 명령을 수행한다.</h3>
<h3 id="streammap">stream.map()</h3>
<ul>
<li>map()메소드는 객체를 데이터로 바꾸는 것(x)</li>
<li>스트림의 값을 변환한다. </li>
</ul>
<h3 id="streamfilter">stream.filter()</h3>
<ul>
<li>말 그대로 조건에 맞는 데이터를 걸러내는 것이라고 생각하면 된다. </li>
</ul>
<h2 id="메소드-참조method-reference">메소드 참조(Method Reference)</h2>
<p>더블콜론을 사용한다.</p>
<ul>
<li>static 메소드 참조( 클래스 내에 선언된 static 메소드를 참조할 수 있다. 클래스명::메소드명)</li>
<li>특정 객체의 인스턴스 메소드 참조 ( System 클래스의 out에 저장된 printStream의 객체를 참조하여 println()을 호출한다.)</li>
<li>특정 유형의 임의의 객체에 대한 인스턴스 메소드 참조(</li>
<li>생성자 참조 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JVM은 꼭 알아야 합니다... ]]></title>
            <link>https://velog.io/@dev_isaac/JVM</link>
            <guid>https://velog.io/@dev_isaac/JVM</guid>
            <pubDate>Sat, 26 Dec 2020 16:17:19 GMT</pubDate>
            <description><![CDATA[<p>*<em>※ 이 시리즈의 내용은 매우 기본적이거나 쉬울 수도 있기 때문에 놀라실 수도 있습니다. 개발자들의 주의를 요합니다. *</em>
<img src="https://images.velog.io/images/dev_isaac/post/29b24d66-f1c3-4e80-8d0d-6b9bf2230b35/Screenshot_8.png" alt=""></p>
<hr>
<p>경험있고 능력있는 개발자라면 코드를 짤 때 어플리케이션의 성능과 안정성 등을 고려할 것이지만, 
부끄럽게도 나는 어플리케이션의 성능과 안정성보다는 로직의 구현 자체에 신경을 쓰는 수준이라는 생각이 드는 경향이 있다고 느껴지는 편이라고 여겨진다...ㅠㅠ(<del>인정하고 싶어하지 않는 몸부림ㅠㅠㅠㅠ</del>)
<img src="https://images.velog.io/images/dev_isaac/post/27996b23-208a-4041-8566-29bf1479135c/%EC%95%A0%EB%B9%84%EC%B6%94%EC%8A%AC%ED%94%94.jpg" alt=""></p>
<p>코드를 실행하고 내 눈앞에 결과가 나타나기까지의 과정의 중심에는 <strong>JVM</strong>이 있다. <strong>JVM을 빼놓고는 JAVA를 말할 수 없으니</strong> 꼭 이 기회에 짚고 넘어가 보자..!!</p>
<p><br><br><br></p>
<h2 id="jvm은-무슨-일을-하나">JVM은 무슨 일을 하나?</h2>
<blockquote>
<ul>
<li>실행될 클래스 파일을 메모리에 로드 후 초기화 작업 수행</li>
</ul>
</blockquote>
<ul>
<li>메소드와 클래스변수들을 해당 메모리 영역애 배치</li>
<li>클래스로드가 끝난 후 JVM은 main 메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓음</li>
<li>다음 라인을 진행하면서 상황에 맞는 작업 수행(함수 호출, 객체 할당 등)</li>
</ul>
<h2 id="jvm은-운영체제로부터-독립적이다">JVM은 운영체제로부터 독립적이다.</h2>
<h3 id="어떻게">어떻게?</h3>
<blockquote>
<p>일단 우리가 운영체제에서 Java를 사용하려면 JDK를 설치해야 한다. 
여기서 이 JDK는 운영체제별 종류가 다르다. 
JDK안에는 JRE, API, JVM이 포함되어 있다. 
즉, 운영체제마다 다른 JVM이 제공되기 때문에 독립적일 수 있다. (굳이 말하자면 JDK에 종속적이라고 할 수 있겠다.)</p>
</blockquote>
<h2 id="jvm-실행-절차">JVM 실행 절차</h2>
<p>*<em>JVM은 byteCode 파일을 기계어 코드로 변환하여 실행하는 역할을 한다. *</em></p>
<blockquote>
<ol>
<li>Java로 작성한 코드(.java)가 컴파일 </li>
<li>바이트코드(.class)파일로 만들어짐</li>
<li>이 파일은 JVM을 거쳐서 기계어 코드파일로 변환된다. </li>
</ol>
</blockquote>
<p>*<em>아래 이미지를 보자. *</em><br><img src="https://images.velog.io/images/dev_isaac/post/5b09902a-9e3b-4ad2-aa43-64478ad875f9/Screenshot_1.png" alt=""></p>
<p>주황색 영역부터 JVM의 영역이다. 
Class Library와 Java Byte Code가 JVM에게 전달되는데, 
JVM 내부적으로 Class Loader라는 녀석이 이것을 전달받는다. </p>
<h3 id="1-class-loader">1. Class Loader</h3>
<p>*<em>클래스로더는 실행에 필요한 모든 실행파일을(.class) 찾는다. *</em></p>
<p>클래스로더는 아래와 같은 계층구조를 갖는다.
<img src="https://images.velog.io/images/dev_isaac/post/095d0d0c-7be0-48f8-bab0-1cb95eef9119/%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A1%9C%EB%8D%94%EA%B3%84%EC%B8%B5.png" alt="">
(Java8기준이며, Java 9부터는 … 3가지 기본클래스로더와 원칙은 유효하나 모듈시스템도입에 따라 구현내용이 바뀌었다고 합니다.)</p>
<h4 id="1-bootstrap-classloader">1) Bootstrap ClassLoader</h4>
<ul>
<li>3가지 중 최상위 클래스이다. </li>
<li><JAVA_HOME>/jre/lib에 담긴 자바 라이브러리를 로딩한다.</li>
<li>Native C로 구현됨.</li>
</ul>
<h4 id="2-extension-classloader">2) Extension ClassLoader</h4>
<ul>
<li><JAVA_HOME>/jre/lib/ext 폴더에 담긴 자바의 확장 클래스파일을 로딩한다. </li>
<li>Java로 구현됨.</li>
</ul>
<h4 id="3-application-classloader">3) Application ClassLoader</h4>
<ul>
<li>-classpath(또는 -cp)폴더에 있는 클래스를 로딩한다. </li>
<li>Java로 구현됨.</li>
<li>개발자가 직접 작성한 코드를 로딩한다. <br>

</li>
</ul>
<p><strong>위의 클래스들은 아래 3가지 원칙에 따라 동작한다.</strong></p>
<ul>
<li>Delegation Principle
클래스로더는 상위 클래스로더로 로딩요청을 위임합니다. 부트스트랩 로더에서부터 로딩요청을 수행하고 하위 클래스로더로 요청을 넘깁니다.</li>
<li>Visibility Principle
범위 규칙을 적용합니다. 하위클래스로더는 상위클래스로더의 클래스를 찾을 수 있지만 , 상위클래스로더는 하위클래스 로더가 로딩한 클래스를 사용할 수 없습니다.</li>
<li>Uniqueness Principle
하위 클래스로더는 상위 클래스로더가 로딩한 클래스를 다시 로딩하지 않습니다.</li>
</ul>
<h3 id="2-바이트-코드-검증-byte-code-verifier">2. 바이트 코드 검증 (Byte code verifier)</h3>
<p>클래스 로더가 모든 실행 파일을 준비하면 이 파일의 코드가 올바른지 검증한다. 코드가 정해진 규칙에 따라 작성되었는지 등을 검증한다.</p>
<h3 id="3-기계어-코드로-변환">3. 기계어 코드로 변환</h3>
<p>Java의 실행파일은 바이트코드이기 때문에 실행될 때 다시 한번 기계가 읽을 수 있는 형태로 인터프리터를 통해 해석된다.</p>
<h4 id="jvm이-자바-실행파일을-기계어-코드로-변환하는-방식에는">JVM이 자바 실행파일을 기계어 코드로 변환하는 방식에는</h4>
<ul>
<li>인터프리터</li>
<li><a href="https://velog.io/@dev_isaac/JIT-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%ACJust-in-Time">JIT</a> (Just In Time) compiler
가 있다.</li>
</ul>
<h2 id="gc와-execution-engine">GC와 Execution Engine</h2>
<ul>
<li><strong>Garbage Collector</strong> : JVM은 Garbage Collector를 통해 메모리 관리 기능을 자동으로 수행한다. 애플리케이션이 생성한 객체의 생존 여부를 판단하여 더 이상 사용되지 않는 객체를 해제하는 방식으로 메모리를 자동 관리한다.</li>
<li><strong>Execution Engine</strong> : Class Loader를 통해 JVM 내의 런타임 데이터 영역에 배치된 바이트 코드를 실행한다. 이 때, Execution Engine은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.</li>
</ul>
<br>

<h2 id="runtime-data-areas">Runtime Data Areas</h2>
<blockquote>
<p>JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다. Class Loader에서 준비한 데이터들을 보관하는 저장소이다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/dev_isaac/post/10e83e75-fed8-4f48-8508-7654d07bead4/Screenshot_1.png" alt=""></p>
<h3 id="1-method-static-area">1. Method (Static) Area</h3>
<p>JVM이 읽어들인 클래스와 인터페이스에 대한 Runtime Constant Pool, 멤버 변수(필드), 클래스 변수(Static 변수), 생성자와 메소드를 저장하는 공간이다. </p>
<h3 id="2-runtime-constant-pool">2. Runtime Constant Pool</h3>
<ul>
<li>메소드 영역에 포함되지만 독자적 중요성이 있다.</li>
<li>클래스 파일 constant_pool 테이블에 해당하는 영역이다.</li>
<li>클래스와 인터페이스 상수, 메소드와 필드에 대한 모든 레퍼런스를 저장한다.</li>
<li>JVM은 Runtime Constant Pool을 통해 해당 메소드나 필드의 실제 메모리 상 주소를 찾아 참조한다.</li>
</ul>
<h4 id="-메소드-영역런타임-상수-풀의-사용기간-및-스레드-공유-범위">※ 메소드 영역/런타임 상수 풀의 사용기간 및 스레드 공유 범위</h4>
<ul>
<li>JVM 시작시 생성</li>
<li>프로그램 종료 시까지</li>
<li>명시적으로 null 선언 시</li>
<li>구성 방식이나 GC 방법은 JVM 벤더마다 다를 수 있다.</li>
</ul>
<h3 id="3-heap-area">3. Heap Area</h3>
<ul>
<li>JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.</li>
<li>New 연산자로 생성된 객체 또는 객체(인스턴스)와 배열을 저장한다.</li>
<li>힙 영역에 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.</li>
<li>참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다.</li>
<li>힙 영역의 사용기간 및 스레드 공유 범위<ul>
<li>객체가 더 이상 사용되지 않거나 명시적으로 null 선언 시</li>
<li>GC(Garbage Collection) 대상</li>
<li>구성 방식이나 GC 방법은 JVM 벤더마다 다를 수 있다.</li>
<li>모든 스레드에서 공유한다.</li>
</ul>
</li>
</ul>
<h3 id="4-stack-area">4. Stack Area</h3>
<ul>
<li>각 스레드마다 하나씩 존재하며, 스레드가 시작될 때 할당된다.</li>
<li>메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다.</li>
<li>선입후출(FILO, First In Last Out) 구조로 push와 pop 기능 사용</li>
<li>메소드 호출 시 생성되는 스레드 수행정보를 기록하는 Frame을 저장</li>
<li>메소드 정보, 지역변수, 매개변수, 연산 중 발생하는 임시 데이터 저장</li>
<li>기본(원시)타입 변수는 스택 영역에 직접 값을 가진다.</li>
<li>참조타입 변수는 힙 영역이나 메소드 영역의 객체 주소를 가진다.</li>
</ul>
<h3 id="5-pc-register">5. PC Register</h3>
<ul>
<li>Thread가 생성될 때마다 생기는 공간으로 Thread가 어떠한 명령을 실행하게 될지에 대한 부분을 기록한다. </li>
<li>JVM은 Stack-Base 방식으로 작동한다. </li>
<li>JVM은 CPU에 직접 Instruction을 수행하지 않고, Stack에서 Operand를 뽑아내 이를 별도의 공간에 저장하는 방식을 취하는데, 이러한 메모리 공간을 PC Register라고 한다.   </li>
</ul>
<h3 id="6-native-method-stack-area">6. Native Method Stack Area</h3>
<ul>
<li>자바 외 언어로 작성된 네이티브 코드를 위한 Stack이다.</li>
<li>즉, JNI(Java Native Interface)를 통해 호출되는 C/C++ 등의 코드를 수행하기 위한 스택이다.</li>
<li>네이티브 메소드의 매개변수, 지역변수 등을 바이트 코드로 저장한다.</li>
</ul>
<blockquote>
<p>참고했습니다.</p>
</blockquote>
<ul>
<li><a href="https://hoonmaro.tistory.com/19">https://hoonmaro.tistory.com/19</a> [훈마로의 보물창고]</li>
<li><a href="https://medium.com/pocs/jvm%EC%9D%B4-%EC%9E%90%EB%B0%94%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%84-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EA%B3%BC%EC%A0%95-3ac22cb22916">https://medium.com/pocs/jvm%EC%9D%B4-%EC%9E%90%EB%B0%94%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%84-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EA%B3%BC%EC%A0%95-3ac22cb22916</a></li>
<li><a href="https://ifcontinue.tistory.com/9">https://ifcontinue.tistory.com/9</a></li>
<li><a href="https://www.holaxprogramming.com/2013/07/16/java-jvm-runtime-data-area/">https://www.holaxprogramming.com/2013/07/16/java-jvm-runtime-data-area/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HotSpotJVM??]]></title>
            <link>https://velog.io/@dev_isaac/HotSpot-JVM</link>
            <guid>https://velog.io/@dev_isaac/HotSpot-JVM</guid>
            <pubDate>Sat, 26 Dec 2020 14:58:54 GMT</pubDate>
            <description><![CDATA[<p>*<em>※ 이 시리즈의 내용은 매우 기본적이거나 쉬울 수도 있기 때문에 놀라실 수도 있습니다. 개발자들의 주의를 요합니다. *</em>
<img src="https://images.velog.io/images/dev_isaac/post/9876e119-3ac6-4c11-b2d0-6add49fa4b44/Screenshot_8.png" alt=""></p>
<hr>
<h2 id="hotspot-핫스팟🤔">HotSpot? 핫스팟?🤔</h2>
<p>사실 HotSpot이라는 단어를 들었을 때 가장 먼저 떠오른 의미는 </p>
<blockquote>
<p>핫스팟 또는 핫스폿(영어: hotspot)은 스마트폰, 노트북을 포함한 이동 단말기로 라우터 등 무선 액세스 포인트가 설치된 지역에서 무선 네트워크(WLAN)에 접속하여 초고속 인터넷과 각종 콘텐츠를 이용할 수 있게 하는 서비스</p>
</blockquote>
<p>그동안 인터넷 와이파이 관련된 핫스팟만 알았지..
JVM을 말하는 것인 줄은 이번에 알았다...</p>
<p><img src="https://images.velog.io/images/dev_isaac/post/c82df0e5-69f7-46f8-bc7e-cae04f6f63aa/%EC%95%88%ED%83%80%EA%B9%8C%EC%9B%80.png" alt="">
나란 🐕발자.. 참 대단합니다... 허허허</p>
<hr>
<p>근데 막상 알아보니 HotSpot이라는 단어를 JVM에 사용한 이유가 생각보다 단순하다. </p>
<blockquote>
<p><strong>JDK1.3 전에 나왔던 가상 머신과 구분하기 위한 이름이라고 생각하면 된다. 
참고로 자바를 만드는 오라클 사이트에서는 이전 버전의 JVM을 Classic VM이라고 표현하고 있다.</strong></p>
</blockquote>
<div style="text-align:right;"> 출처 : 『JAVA의 신』 - 이상민 저</div>

<p>JVM에 대한 설명은 <a href="https://medium.com/pocs/jvm%EC%9D%B4-%EC%9E%90%EB%B0%94%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%84-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EA%B3%BC%EC%A0%95-3ac22cb22916">이미 훌륭하게 정리된 글의 링크</a>를 참조하도록 하자.</p>
<h3 id="hotspot-jvm에서는-두-가지의-컴파일러가-제공된다">HotSpot JVM에서는 두 가지의 컴파일러가 제공된다.</h3>
<ul>
<li>클라이언트 컴파일러</li>
<li>서버 컴파일러</li>
</ul>
<p>불과 몇년 전만 하더라도 많은 CPU코어를 사용할 수 없었고 대부분 코어의 개수가 하나였다. 이런 사용자의 상황을 위해 만들어진 것이 <strong>클라이언트 컴파일러</strong>였다. </p>
<h4 id="클라이언트-컴파일러의-간단한-특징을-보자면">클라이언트 컴파일러의 간단한 특징을 보자면,</h4>
<ul>
<li>애플리케이션 시작 시간을 빠르게 하기 위해 만들었다.</li>
<li>적은 메모리를 점유하도록 했다. </li>
<li>애플리케이션 수행 속도에 중점을 뒀다.</li>
<li>서버 컴파일러보다 먼저 컴파일을 시작한다.</li>
<li>최적화를 위한 대기시간이 짧다.</li>
<li>Start-Up 시간이 빠르다. 하지만 최적화가 덜하기 때문에 코드실행은 서버가 더 빠르다. </li>
</ul>
<h4 id="서버-컴파일러의-특징은-아래와-같다">서버 컴파일러의 특징은 아래와 같다.</h4>
<ul>
<li>컴파일전에 많은 정보를 수집하여 최적화에 중점을 둔다</li>
<li>서버 컴파일러는 절대로 모든 코드를 컴파일하지 않는다</li>
</ul>
<br>

<p>*<em>그렇다면 클라이언트/서버 컴파일러의 구분 기준은 뭘까? *</em></p>
<ul>
<li>2개 이상의 물리적 프로세서</li>
<li>2GB 이상의 물리적 메모리</li>
</ul>
<p>위의 조건에 만족하면 Oracle에서 만든 JVM은 서버 컴파일러를 선택한다. </p>
<p>명시적으로 컴파일러를 지정하려면 아래와 같이 java 명령과 클래스 이름 사이에 옵션을 추가하면 된다.</p>
<blockquote>
<p><code>java -server 클래스명</code>
<code>java -client 클래스명</code></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JIT 컴파일러(Just-in-Time) ]]></title>
            <link>https://velog.io/@dev_isaac/JIT-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%ACJust-in-Time</link>
            <guid>https://velog.io/@dev_isaac/JIT-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%ACJust-in-Time</guid>
            <pubDate>Sat, 26 Dec 2020 06:43:07 GMT</pubDate>
            <description><![CDATA[<p>*<em>※ 이 시리즈의 내용은 매우 기본적이거나 쉬울 수도 있기 때문에 놀라실 수도 있습니다. 개발자들의 주의를 요합니다. *</em>
<img src="https://images.velog.io/images/dev_isaac/post/8e6314a0-16dd-4fe8-aab3-f550f794c37c/Screenshot_8.png" alt=""></p>
<hr>
<h3 id="jit">JIT?</h3>
<p>JIT는 JVM내부에서 바이트코드를 기계어로 변환하는 방식으로서 Just-In-Time의 약자다. </p>
<ul>
<li>아래 그림에서 컴파일된 ByteCode와 기계코드 사이에 있는 JVM에서 JIT가 수행된다. 
<img src="https://images.velog.io/images/dev_isaac/post/1f48819d-5473-49b6-a54c-fb0e8ee9b585/%EC%9E%90%EB%B0%94%20%EC%8B%A4%ED%96%89%EC%A0%88%EC%B0%A8.png" alt="">
이미지 출처 : <a href="https://images.app.goo.gl/LsXuRMLSYmfSDWzQ9">https://images.app.goo.gl/LsXuRMLSYmfSDWzQ9</a></li>
</ul>
<h3 id="컴파일-방식">컴파일 방식</h3>
<p>컴파일 방식은 인터프리트 방식과 정적 컴파일 방식이 있다. </p>
<ul>
<li>인터프리트 방식 : 프로그램 실행시마다 기계어로 변환하는 작업을 수행하는 방식</li>
<li>정적 컴파일 방식 : 실행 전 기계어로 미리 변환 후 실행하는 방식이며, 딱 한번만 수행된다. </li>
</ul>
<p><strong>JIT는 이 두가지를 혼합한 것이다.</strong> 인터프리터에 의해 변환이 지속적으로 수행되지만, 필요한 코드 정보는 캐시에 담아두었다가(메모리에 올려둠) 재사용하는 방식이다. </p>
<h3 id="장점">장점</h3>
<p>반복적으로 수행되는 코드에 대해 매우 빠른 성능을 보인다.</p>
<h3 id="단점">단점</h3>
<p>처음 시작 시에 변환 단계를 거치기 때문에 성능이 느리다. (하지만 최근에는 CPU성능과 JDK성능이 개선되어 많이 개선됐다고 한다. )</p>
<p><strong>위의 내용에서 JVM -&gt; 기계코드로 변환되는 부분에서 JIT가 수행된다.</strong></p>
<p>출처 : 『JAVA의 신』 - 이상민 저</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[위기의 개발자(feat.나님)]]></title>
            <link>https://velog.io/@dev_isaac/N%EB%85%84%EC%B0%A8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EB%88%88%EB%AC%BC%EC%9D%98-%EA%B8%B0%EB%B3%B8%EA%B8%B0-%EB%8B%A4%EC%A7%80%EA%B8%B0-JAVA</link>
            <guid>https://velog.io/@dev_isaac/N%EB%85%84%EC%B0%A8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EB%88%88%EB%AC%BC%EC%9D%98-%EA%B8%B0%EB%B3%B8%EA%B8%B0-%EB%8B%A4%EC%A7%80%EA%B8%B0-JAVA</guid>
            <pubDate>Sat, 26 Dec 2020 06:26:42 GMT</pubDate>
            <description><![CDATA[<p>본인은 개발자로서 이 업계에 몸을 담아 N년차 개발자가 되었다. 
하지만 연차가 쌓임과 동시에 느껴지는 연차에 대한 부담스...</p>
<p>급기야 N년차에는 저렇게 되지 말아야지 하고 다짐했던 부분들이 나에게 고스란히 나타났다...ㅠㅠ </p>
<h4 id="그거슨-기본기-부족">그거슨 기본기 부족...</h4>
<p>개발자로서 취직 후 열심히 산다고 살았는데... 상황에 따라 급한 것에만 치중하다보니 이런 사태가 벌어진 것 같다. 장기적인 시각으로 개발자로서 앞으로 살아가려면 지금의 실력으로는 갈 곳이 없ㅇ....
<img src="https://images.velog.io/images/dev_isaac/post/5019a1c0-f03e-4a1e-ac80-46f160404f21/%EC%9E%85%ED%8B%80%EB%A7%89.jpg" alt=""></p>
<p>결국 현실을 자각하여 </p>
<blockquote>
<p>천리길도 한걸음부터의 마음으로 JAVA 기본서를 진지하게 다시 보기로 결심했다.</p>
</blockquote>
<p>*<em>초조함과 불안을 에너지삼아서라도 한단계 성장하는 계기가 되기를 기도하며 JAVA개발자로서 꼭 알아야 할 내용들을 이곳에 정리해보고자 한다. *</em></p>
]]></description>
        </item>
    </channel>
</rss>