728x90
반응형
728x90
반응형
반응형

JVM (Java Virtual Machine)

  • 자바 가상 머신으로 자바 바이트 코드(.class 파일)를 OS에 특화된 코드로 변환(인터프리터와 JIT 컴파일러)하여 실행
  • 바이트 코드를 실행하는 표준(JVM 자체는 표준)이자 구현체(특정 밴더가 구현한 JVM)
  • 특정 플랫폼에 종속적

JRE (Java Runtime Environment): JVM + 라이브러리

  • 자바 애플리케이션을 실행할 수 있도록 구성된 배포판
  • JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있음
  • 개발 관련 도구(JDK)는 포함하지 않음

JDK (Java Development Kit): JRE + 개발 툴

  • JRE + 개발에 필요할 툴
  • 소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적
  • 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않음
  • Write Once Run Anywhere

Java

  • 프로그래밍 언어
  • JDK에 들어있는 자바 컴파일러(javac)를 사용하여 바이트코드(.class 파일)로 컴파일
  • 자바 유료화? 오라클에서 만든 Oracle JDK 11 버전부터/ 상용으로 사용할 때 유료이며 나머지는 무료

JVM 구조

jvm

Class Loader

  • .class에 있는 바이트코드를 읽고 메모리에 저장
  • loading: 클래스 읽어오는 과정
  • linking: 레퍼런스를 연결하는 과정
  • initialization: static 값들 초기화 및 변수에 할당

메모리

  • 메소드 영역에는 클래스 수준의 정보(클래스 이름, 부모 클래스 이름, 메소드, 변수) 저장
  • 힙 영역에는 객체를 저장
  • 스택 영역에는 스레드 마다 런타임 스택을 만들고, 그 안에 메소드 호출을 스택 프레임이라 부르는 블록으로 쌓음. 스레드 종료하면 런타임 스택도 삭제됨
  • PC(Program Counter) 레지스터: 스레드 마다 스레드 내 현재 실행할 instruction의 위치를 가리키는 포인터가 생성됨
  • 네이티브 메소드 스택: Native Method를 호출하는 코드를 수행하기 위한 스택

Execution engine

  • interpreter: 바이트 코드를 한 줄씩 실행
  • JIT compiler: 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러는 반복되는 코드를 모두 네이티브 코드로 바꿈. 그다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용할 수 있도록 지원
  • GC(Garbage Collector): 더이상 참조되지 않는 객체를 모아서 주기적으로 정리하는 프로그램

JNI(Java Native Interface)

  • 자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있게 함
  • native 키워드를 사용한 메소드 호출

Native Method Library

  • C, C++로 작성된 라이브러리

 

garbage?

  • 주소를 잃어버려서 사용할 수 없는 메모리, 정리되지 않은 메모리, dangling object

garbage collection(GC)?

  • garbage의 메모리 해제; JVM이 한가할 때(idle) 혹은 메모리가 부족해져 OS에게 추가로 메모리를 할당해달라고 요청할 때 실행

 

JVM의 Heap영역의 대전제

  • 대부분의 객체는 대부분 일회성이며 금방 접근 불가능한 상태(Unreachable)가 된다.
  • 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
  • 생존 기간에 따라 heap을 두 가지 영역으로 쪼갬(Young, Old 영역) - 초기에는 Perm 영역이 존재하였지만 Java8부터 제거됨

 

minor gc?

  • 새롭게 생성된 객체가 할당(Allocation)되는 Young 영역에 대한 가비지 컬렉션(Garbage Collection)
  • 대부분의 객체가 금방 Unreachable 상태가 되기 때문에, 많은 객체가 Young영역에 생성되었다가 사라짐
    • The Young Generation is further divided into three spaces: Eden space and two Survivor spaces (S0 and S1).
  • eden 영역이 꽉 찬 경우 발생, 빠름
    • eden 영역에서 사용되지 않아진 객체의 메모리 해제
    • eden 영역에서 살아남은 객체는 s1/s2로 이동(s1이 꽉차면 s2, vice versa)
       

major gc/full gc?

  • minor gc속에서 살아남은 객체가 복사되는 Old 영역에 대한 가비지 컬렉션(Garbage Collection)
  • 복사되는 과정에서 대부분 Young 영역보다 크게 할당되며, 크기가 큰 만큼 가비지는 적게 발생함
  • old 영역이 꽉 찬 경우 발생, 느림

 

구체적으로 어떻게?

  • Stop the world(STW): GC를 실행하기 위해 JVM이 어플리케이션의 실행을 멈추는 작업
    • GC를 실행하는 스레드를 제외한 모든 스레드의 작업이 중단되고, GC가 완료되면 작업 재개됨
    • GC옵션이나 알고리즘으로 STW시간을 단축할 수 있음
  • Mark and Sweep: 
    • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
    • Sweep: Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업
    • Stop The World를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각이 어떤 객체를 참고하고 있는지를 탐색하며 mark and sweep 작업을 진행함

algorithm

java11 default gc

-XX:+UseG1GC

힙을 격자/작은 지역으로 쪼개서 특정 지역별로 gc가 일어남.

그래서 예측가능하고 정지시간이 짧음,

성능이 좋고 메모리 효율이 좋음,

gc처리가 병렬처리 가능

튜닝 가능

 

java8 default gc

-XX:+UseParallelGC

G1GC가 자바7부터 나왔기 때문에 사용 가능 다만 기본값은 아니라는 점

 

주로 사용되는 GC

  1. G1 garbage collector(G1GC)
    1. java 7+ 사용가능
  2. Z garbage collector(ZGC)
    1. java 11+ 사용가능
  3. Parallel garbage collector
    1. java 5+ 사용가능
728x90
반응형

'개발 > java' 카테고리의 다른 글

[jmh] benchmark test  (0) 2022.08.04
[powermock] mock static method  (0) 2022.07.21
[keyword] transient in serialization  (0) 2022.02.16
[junit5] no test found / checked exception is invalid  (0) 2022.02.07
[junit] test runner  (0) 2022.01.03
반응형

코드를 보다보면 종종 transient 라는 키워드를 볼 때가 있다.

public class TransferManager {
    @Autowired
    private transient CommandGateway commandGateway;
    private TransferCommandFactory commandFactory;
...
}

 

의미?

Serialization is the process of converting an object into a byte stream, and deserialization is the opposite of it.
When we mark any variable as transient, then that variable is not serialized.

Serialization is the process of making the object's state persistent. That means the state of the object is converted into a stream of bytes to be used for persisting (e.g. storing bytes in a file) or transferring (e.g. sending bytes across a network). In the same way, we can use the deserialization to bring back the object's state from bytes. the process of making the object's state persistent.

직렬화(serialization)는 object를 byte stream으로 컨버팅하는 과정이며 역직렬화는 반대 과정을 뜻한다. 직렬화는 객체의 상태를 유지하게하는 과정 중 하나인데, 보통 직렬화를 해서 파일을 만들거나 네트워킹 작업을 하기 때문이다.

transient로 변수를 마킹할 경우 그 변수는 직렬화에 포함되지 않는다(null로 표현됨).

단지 메모리 안에서만 사용되는 변수

 

어디에 주로 사용되나?

  • 한 인스턴스 안에서 계산되어진 값을 임시로 들고 있을 때(for derived fields)
  • 객체의 상태를 나타내는 값이 아닌 변수(not the state of the object)
  • 직렬화가 되지 않는 변수(non-serializable references; throw “java.io.NotSerializableException”)

 

참고1. @Transient

  • entity안에서 사용되는 어노테이션으로 필드를 DB에 저장하지 않도록 해줌.
  • 메모리에 올려다가 놓고 쓰긴하지만 영속성을 주지 않는다는 뜻(not persistent)

참고2. transient vs volatile

  • volitiled은 항상 (thread dependency가 있는 cpu cache가 아닌) 메인 메모리에서 읽어오는 값
  • 메인 메모리에서 read/write하기 때문에 비용이 더 큼(성능 악화)
  • 여러 스레드에서 같은 값으로 사용가능
  • Multi Thread 환경에서 하나의 Thread만 read & write하고 나머지 Thread가 read하는 상황에서 가장 최신의 값을 보장

 

다른 자바 키워드: https://www.w3schools.com/java/java_ref_keywords.asp

 

Java Keywords

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

728x90
반응형

'개발 > java' 카테고리의 다른 글

[jmh] benchmark test  (0) 2022.08.04
[powermock] mock static method  (0) 2022.07.21
[java] jvm, java, gc  (0) 2022.02.24
[junit5] no test found / checked exception is invalid  (0) 2022.02.07
[junit] test runner  (0) 2022.01.03
반응형

환경: springboot2.6.2, intellij2021.2.2

junit5기반의 테스트 코드를 돌릴 때 아래와 같은 에러가 나면서 테스트가 안 돌아갈 때가 있다.

Execution failed for task ':query:test'.
> No tests found for given includes: [com.cqrs.query.service.RetryServiceTest.retryTest_with_bean](filter.includeTestsMatching)
import org.junit.jupiter.api.Test;
...

@SpringBootTest
class RetryServiceTest {

    @Autowired
    private RetryService retryService;
    @MockBean
    private AccountRepository accountRepository;

    @Test
    void retryTest_with_bean(){
        //when
        Mockito.when(accountRepository.findByHolderId(ArgumentMatchers.anyString())).thenThrow(NoSuchElementException.class);
        assertThrows(NoSuchElementException.class, () -> retryService.getHolderAccountSummary());

        //then
        Mockito.verify(accountRepository, Mockito.times(3)).findByHolderId(ArgumentMatchers.anyString());
    }
}

아래와 같이 intellij의 run test using설정이 gradle(default)로 되어 있을텐데, 저 값을 gradle -> intellij로 바꾸면 실행된다..

intellij settings

 


추가)

아래와 같이 Mockito.when().thenThrow() 로 exception 발생 시 Exception.class로 지정하면 에러가 나면서 실행이 되지 않는다.

 Mockito.when(accountRepository.findByHolderId(ArgumentMatchers.anyString())).thenThrow(Exception.class);
 -----------
 //에러
Checked exception is invalid for this method!

 

Checked Exception 이란 위 그림에서 초록색 exception 인데, 이를 unchecked exception, 즉 RunTimeException이나 그 하위 exception 으로 바꿔주면 된다.

참고) exception 구분

728x90
반응형

'개발 > java' 카테고리의 다른 글

[jmh] benchmark test  (0) 2022.08.04
[powermock] mock static method  (0) 2022.07.21
[java] jvm, java, gc  (0) 2022.02.24
[keyword] transient in serialization  (0) 2022.02.16
[junit] test runner  (0) 2022.01.03
반응형
@RunWith
  •  프레임워크의 테스트 실행 방법을 확장할 때 사용하는 annotation
  • default : JUnit에 내장된 BlockJUnit4ClassRunner.class

 

@RunWith(PowerMockRunner.class)
@PrepareForTest({RestTemplate.class, AvatarApi.class})
  • final, static, private method/constructor를 mock하게 해주는 테스팅 Runner
  • @PrepareForTest 에는 mock되어야 하는 클래스 선언
  • static method를 가진 class를 mock 할 경우, mockStatic() 사용
  • 미리 클래스 파일을 조작하고 디스크에 저장한 뒤 이 클래스 파일을 런타임에서 사용하는 방식(Javaasist)

참고) powerMock을 사용하면 jacoco test coverage가 먹지 않는다.

 
@RunWith(MockitoJUnitRunner.class)
  • Mockito를 사용하여 mock객체를 주입받아 테스트하기 위해 @Mock, @InjectMocks, @Spy 등을 제공하는 테스팅 Runner
  • spring 관련 설정이 필요 없음

 

@RunWith(SpringJUnit4ClassRunner.class) 
= @RunWith(SpringRunner.class)
  • 테스트환경에서 @Autowired를 통해 Bean을 주입받을 수 있는 Spring Application Context를 제공하는 테스팅 Runner
  • spring 설정 참조가 필요한 클래스의 단위 테스트 시 사용
    • 테스트용 별도 프로퍼티 사용이 필요한 테스트 작성 시
  • 통합테스트 시 사용
    • 컨트롤러부터 api/repository까지 흐름 테스트 시
    • 테스트용 설정 파일 필요

@RunWith(Suite.class) 
@SuiteClasses({ 
  NoticeBOImplTest.class, 
  NoticeMasterDAOImplTest.class, 
  WCMSNoticeDAOTest.class, 
  HBBSNoticeDAOTest.class 
})
  • 여러 클래스가 한 번에 테스트 되어야 할 때 사용
  • @Suite 는 테스트 하고자 하는 클래스들을 나열한다. 이 클래스들에 있는 @Test 메서드들을 전부 실행한다.

 

@RunWith(JUnit4.class)

 

Junit 5

https://gmlwjd9405.github.io/2019/11/26/junit5-guide-basic.html

주의사항: junit4와 import package가 다르니 주의해야한다!

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
  • @Before -> BeforeAll, BeforeEach 로 해야하고, 반드시 static으로 선언해야한다.
728x90
반응형

'개발 > java' 카테고리의 다른 글

[jmh] benchmark test  (0) 2022.08.04
[powermock] mock static method  (0) 2022.07.21
[java] jvm, java, gc  (0) 2022.02.24
[keyword] transient in serialization  (0) 2022.02.16
[junit5] no test found / checked exception is invalid  (0) 2022.02.07

+ Recent posts