XML Parser

XML Parser?

XML이란

XML은 eXtensible Markup Language의 약자! 데이터를 주고 받을 때 어던 형태로 주고 받을 지 정의하고 구조를 공유하고 서로 전달 할 수 있게 도와주는 약속이다.

어떻게 사용?

주고 받을 측에서는 어떻게 정의되어 있는지 알아야하고 그 구조에 맞춰서 데이터를 추출해야 한다. 그게 Parsing 한다고 하는거. XML을 파싱하는 도구(Parser)는 많은데 Java에서는 SAX DOM XSLT 등이 있다.

Java XML Parser

SAX

SAX파서는 XML 문서를 순차적으로 읽고, 엘리먼트를 만날 때마다 정해준 핸들러를 통해 파싱한다.

장점 : 순차적으로 읽으니까 비교적 빠르다! 단점 : 모든 이벤트 핸들러를 처리해야 할 필요는 없지만 상대적으로 데이터를 어떻게 처리할지, 사용할지를 결정하고 구현해야 돼서 까다롭다.

DOM

DOM파서는 XML 문서를 통째로 한 번 읽고 데이터를 만들고 필요한 부분을 추출한다.

장점 : 상대적으로 간편하게 쓸 수 있다. 단점 : XML 문서를 한 번 쭉 읽고 데이터를 추출할 수 있으므로 속도가 느리다.

리소스

일반적으로 XML 문서를 파싱하는데 많은 리소스를 잡아먹는다. 더군다나 두 파서의 특징이 다르기 때문에 여기서도 리소스 점유도 차이가 나는데

SAX의 경우 한 줄 씩 읽는다고 했고, DOM은 문서 전체를 한 번 읽고 데이터를 만든다고 했는데… 예상한데로 DOM의 리소스 사용은 훨씬 많다. 시간은 물론이거니와 메모리또한 훨~씬 많이 잡아 먹는다. XML 문서가 커질 수록 감당 안될 정도의 메모리를 사용한다.

Java Tuning 이야기2

Java 클래스의 정보 추출하기

public static void printClasDetial(Object object) {
  	Class clas = object.getClass();

  	System.out.println("Class Name : "+clas.getName());

  	System.out.println("\n====Class Fields====");
  	Field[] fields = clas.getFields();
  	for ( Field f : fields )
  		System.out.println(f.getName());

  	System.out.println("\n====Class Methods====");
  	Method[] methods = clas.getMethods();
  	for (Method method : methods )
  		System.out.println(method);
}

List Map 연산 속도 측정

  • 측정환경
  • Mac OS 10.12.3
  • Intel i5 2.7 GHz
  • 8 GB

java_benchmark

Java Tuning 이야기

Map, Set, List, Queue 의 차이점

우선 자바에서 사용할 수 있는 Collection과 Map의 구성도를 보자. 매번 봤지만 자꾸 까먹고 뭐가 있는지 자세히 모르니까..

Java Collection, Map 클래스 구성도

  • Map

Map

  • Collection

Collection

출처 : https://dzone.com/articles/an-introduction-to-the-java-collections-framework

  1. Map : Key와 Value의 쌍으로 묶여서 저장되는 자료구조로 중복된 Key를 허용하지 않아!
    • Hashtable : 데이터를 해쉬테이블에 담아준다. 동기화 O
    • HashMap : 해쉬테이블이랑 비슷한데 null 허용 안하구 동기화 X
    • TreeMap : red-black에 담는데 Key로 순서를 정함
    • LinkedHashMap : 그냥 해쉬맵이랑 비슷한데 Doubly Linkedlist를 사용한다.
  2. Set : 중복을 허용하지 않는 집합을 처리하는 자료구조
    • HashSet : key를 해쉬로 저장
    • TreeSet : red-black 트리에 저장해서 동시에 정렬, 정렬때문에 느려
    • LinkedSet : 해쉬로 담는데 순서있게.
  3. List : 순서가 있는 집합을 처리하기 위한 자료구조로 중복을 허용한다.
    • Vector : 배열인데 크기를 지정할 필요 없음 동기화 O
    • ArrayList : 벡터랑 비슷한데 동기화 X
    • LinkedList : 배열이랑 비슷한데 Queue를 구현함. 그래서 FIFO
  4. Queue : 여러 개의 객체를 처리하기 전에 담아서 처리할 때 사용하기 위한 자료구조, FIFO
    • PriorityQueue : 추가된 순서 상관없이 먼저 생성된게 먼저나온다..? 그냥 우선순위가지는 큐!
    • LinkedBlockingQueue : 크기를 정할 수 있는, 링크드를 사용하는 큐
    • ArrayBlockingQueue : 크기가 정해져 있는! 큐
    • PriorityBlockingQueue : 크기 안 정해져 있고 우선순위 가지는 큐
    • DelayQueue : 대기하는 시간을 지정할 수 있는 큐
    • SynchronousQueue : 동기화 O
Java GC란?

Java GC란 무엇이고, 어떻게 동작하는가?

그전에 용어 정리

HotSpot

HotSpot is a Java virtual machine for desktop and server computers, maintained and distributed by Oracle Corporation. It features improved performance via methods such as just-in-time compilation and adaptive optimization. - Wikipedia

가상 머신이란다.. JIT나 최적화 같은걸 써서 성능을 끌어올리는 JVM.

JIT 최적화

컴파일 언어라고 모든 소스코드를 컴파일하고 메모리에 올려서 동작하는 줄 알았더니 아니더라. 모든 코드는 우선 인터프리터에 의해서 시작되고 해당 코드가 많이 사용되면 그때 컴파일 대상으로 옮겨서 컴파일하고 사용한다.

  • invocation counter : 메소드를 시작할 때 증가
  • backedge counter : 높은 바이트 코드 인덱스 > 낮은 인덱스로 옮겨갈 때 증가

많이 많이 써서 컴파일 요청 > 컴파일 큐 쌓고 > 컴파일러 스레드가 대상 코드 골라서 > 컴파일 > 소스와 컴파일된 코드를 연결

! 이때 컴파일 중인 코드가 불리면?

인터프리터는 카운터값 초기화하고 그냥 하던데로 할 수도 있고! 이게 기본이고 컴파일 모두 끝날 때까지 기다렸다가 그 코드를 읽을 수 도 있고.

Young영역

자바에서 새로운 객체가 생성되면 이 영역으로 할당된다. Young영역은 또 3 구역으로 나뉜다. Eden, Survivor 2개. 맨 첨에는 Eden에 할당되고 이후 GC에서도 살아 남으면 Survivor로 옮겨진다.

Old영역

young영역에 있는 Survivor에서도! 살아남은 객체들이 Old에 머무른다.

Java GC 종류

jvm_heap

동작하는 곳을 기준으로 Minor GC, Major GC(Full GC)로 나뉜다.

Minor GC

Minor GC는 Young 영역에서 일어나는 GC를 말한다. Eden > Survivor 로 갈 때, 또 Survivor > Survivor로 옮기는 녀석이 Minor GC이다.

객체 생성되면 Eden으로 가고 여기 차면 GC 이 GC할때 사용중인 애들은 Survivor로 가는데 일을 하나 더 함 기존에 Survivor에서 살던 객체들도 GC를 벗어날 수 없는데 여기서 살아남은 애들도 다른 Survivor로 간다. 무조건 한 개는 비어있어야 하고 Eden + Survivor1 => Survivor2로 간다.

이걸 여러번 반복하면서 왔다갔다 하면 Old 영역으로 이동한다.

Major GC

Major GCFull GC라고도 하고 Old 영역에서 일어나는 GC를 일컫는다. 지만! Permanent 영역에서 일어나는 GC도 major GC에 포함되지만 최신 자바에선 빠질 예정이므로. Old만 생각한다.

얘는 Young처럼 몇 구역으로 나뉜게 아니라 그냥 한덩어리인데 어떤 애들이 들어오냐면 Survivor에서 끈질기게 살아남은 녀석들과 객체가 생성될 때 너무나 커서 Eden에서 수용할 수 없는 애들이 들어온다.

얘네들을 GC할 땐 우선 Survivor를 참조하고 있는지 확인한다. 이과정에서 Card table이란걸 사용하고, 모든 객체를 둘러보지 않는다. 그럼 card table만 보고 연결된 객체인지 판별한다음 GC 대상이 된다.

Java GC 방식

Serial GC

minor, major GC를 순차적으로 실행한다. 하나의 CPU를 사용하는데에서 이 방식을 택하고 GC가 돌면 두 종류의 GC 모두 수행하고, 앱 실행은 잠시 멈춘다. 위험하다. 아 그리고 마지막 Old 영역을 컴팩션(한 쪽으로 몰아두는거)한다.

Parallel GC

병렬로 수행하는 애. 이걸로 CPU 노는 시간을 좀 줄일 수 있다. 병렬로 쫘라락 하기 때문에 부하를 줄이고 대기시간 감소시킬 수 있다.

Parallel Compacting GC

Parallel GC랑 비슷한데 Old 영역의 GC에서 차이가 좀 있다. 사용 안하는 객체 표시하고 나서 스윕(시리얼, 병렬에서 사용하는) 말고 종합 단계를 거친다.

  • 스윕단계 : 단일 스레드로 old영역을 쓸어버린다.
  • 종합단계 : 다중 스레드로 old영역을 분리해서 쓸어버린다.

Concurrent Mark-Sweep (CMS) GC

힙 메모리를 크게 잡았을 때 유용하고 단계가 다르다.

  • 초기 쓰레기 표시 > 앱 수행하면서 동시에 GC당할 애들 표시 > 그 중간에 또 생겼을지 모르니 다시 표시 > 쓸어버리는 단계 그리고 컴팩션을 안하니까 한 쪽으로 몰리지 않음

Garage First

g1

young 영역과 old 영역으로 안나뉘고 위 그림과 같이 나뉜다. 저렇게 쪼개서 각각 영역을 분배해 주고 GC할 때 마다 구역을 옮기겨준다.

Java GC 모니터링 도구

자바의 신께서 적으신 블로그. 나중에 찾아가기 쉽게 링크!

jstat, jstatd

HotSpot VM에 들어있는 GC모니터링 도구 jstat은 로컬 시스템에서 볼 수 있는 거고 jstatd는 원격으로 모니터링할 때 사용한다.

Visual GC

Visual GC는 오라클 jdk에서 제공하는 GUI 툴!

JPS

Jps는 자바에서 제공하는 jvm 프로세스 보여주는 도구이다. 유닉스 ps같은 건데 얘는 jvm이 띄운 프로세스 정보들을 보여준다.


출처

jvm heap : http://www.engineersbloc.com/collection/278/

garage first : http://www.herongyang.com/JVM/Memory-Serial-Parallel-Concurrent-Reginalized-Collectors.html

JMX란?

Java Management Extensions의 약자로 자바 기반의 모든 애플리케이션을 모니터링하기 위해서 만든 기술.

JMX 모니터링 도구

  1. Visual VM
  2. jconsole
  3. ApplicationsManager