finalize(): GC calls when Instance is garbage collected. which has no reference. 참고사이트:
hashCode(); when making equals method of Object. we must consider this method().
final: (method or class) will not be inheritted.
finalize(): GC calls when Instance is garbage collected. which has no reference. 참고사이트:
hashCode(); when making equals method of Object. we must consider this method().
final: (method or class) will not be inheritted.
OSGI (Open Services Gateway Initiative) REF-SITE:
- Originally targeted embedded devcies & home service GWs.
- Bundle based Fluent Life-Cycle framework. (Bundle=jar+alpha)
(life-cycle Layer can dynamically install/remove/start/stop bundles)
- JavaObject based SOA
ex) Eclipse Equinox PDE (Plug-in Development Environment)
Apache Felix. Reference-Site
nio2 참고사이트: copy, move, readAllLines, Files.walkFileTree(Path, FileVisitor<T> ), WatchService,
기타7 문법 참고사이트:
1. try-with-resource,
File nFile=new File("abc.txt");
try ( InputStream in = new FileInputStream(nFile) ){
}catch (Exception e){
}
2. String in case,
case "abc":
그 외 될 뻔하다가 적용 안된 거.
A.(multi) catch (|),
B. ?(return null when null).
C.멀티Collection생성자, //ex: new ArrayList {"one", "two", "three"}; => 1.8에서도 안 됨.
You can use the following command to find out the defaults on the system where your applications runs.
java -XX:+PrintFlagsFinal -version
Look for the options MaxHeapSize
(for -Xmx
) and InitialHeapSize
for -Xms
.
On a Unix/Linux system, you can do
java -XX:+PrintFlagsFinal -version | grep HeapSize
GC(Garbage Collection)에는 serial방식과 Parallel방식이 있는데
single thread (32bit window)등 특수환경에서만 serial방식이 쓰이고, 대부분 Parallel 방식이 쓰인다.
serial방식의 경우, 어플리케이션을 freezing시켜 버린다.
GC의 중요한 2가지 기능별 분류:
CMS GC(concurrent-mark-sweep) :
- 동시에 여러Thread를 이용해서 mark하고 sweep.
- 일반적으로 STW(Stop-The-World)를 유발하지 않지만 아래2가지 경우 STW 발생가능..
a. Initial Root 마킹
b. 동작중에 앱의 heap 상태 변경으로 재구동 필요시
G1 GC(Garbage first Collector - JDK1.7u4 에서 4GB 이상 heap을 우선처리하기 위해 등장 함)
- JDK1.8u20 에서는 string dup제거 로직도 추가됨
추가로,
Java8에선 PermGen (class 메타데이타 저장소)가 없어짐. OOM을 많이 유발하던 부분임.
CMS GC의 버그는 1.7에서 해결되었으며,
G1 GC의 버그는 1.8에서 해결됨. : 슬라이드 30페이지
XML파싱 방법에는 문서전체를 로드해서 하는 DOM방식과, 문서를 순차적으로 읽으면서 하는 SAX(Simple Api 4 Xml)방식이 있다. 참고사이트
JDom등의 별도 라이브러리를 쓰는 경우도 있지만,
내장된 XPath가 워낙 간단해서 입문자는 무조건 이방식으로 하면 될 것으로 보인다. 이 XPath는 기존의 DOM 방식이나 SAX방식이 아닌
XDM(Xml Data Model)방식으로 불리는데, 굳이 Dom/SAX와 비교하자면 Dom방식에 약간 더 가깝다고 볼 수 있을 것 같다.
<사용방식>
//어딘가 Web에 연결해서
HttpURLConnection con = (HttpURLConnection)apiUrl.openConnection();
con.setRequestMethod("GET");
//using XPath 로 파싱.
InputSource is = new InputSource( new InputStreamReader(con.getInputStream()));
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(is);
XPath xpath = XPathFactory.newInstance().newXPath();
zone = (String)xpath.evaluate("/result/zoneName", doc, XPathConstants.STRING);
String offTime = (String)xpath.evaluate("/result/gmtOffset", doc, XPathConstants.STRING);
time = timeAdd(timeCords[0], offTime);
1. 몇가지 Regex 샘플.
A."no it's all right lag" 제거 => str.replaceAll ("no (.*)lag", "A")
B. "Availability in 20 days"; 20만 발췌 => str.replaceAll("\\D+", "");
2. json 을 파싱할 때, 필요한 Regex 2개이다. (\=역슬래쉬)
String normal = json.replaceAll("[{\"}]", ""); //remove {,", }
String[] kvset = normal.split(",\\s*"); //split with , and * means space exist or not
표현식 | 설명 |
^ | 문자열의 시작 |
$ | 문자열의 종료 |
. | 임의의 한 문자 (문자의 종류 가리지 않음) 단, \ 는 넣을 수 없음 |
* | 앞 문자가 없을 수도 무한정 많을 수도 있음 |
+ | 앞 문자가 하나 이상 |
? | 앞 문자가 없거나 하나있음 |
[] | 문자의 집합이나 범위를 나타내며 두 문자 사이는 - 기호로 범위를 나타낸다. []내에서 ^가 선행하여 존재하면 not 을 나타낸다. |
{} | 횟수 또는 범위를 나타낸다. |
() | 소괄호 안의 문자를 하나의 문자로 인식 |
| | 패턴 안에서 or 연산을 수행할 때 사용 |
\s | 공백 문자 |
\S | 공백 문자가 아닌 나머지 문자 |
\w | 알파벳이나 숫자 |
\W | 알파벳이나 숫자를 제외한 문자 |
\d | 숫자 [0-9]와 동일 |
\D | 숫자를 제외한 모든 문자 |
\ | 정규표현식 역슬래시(\)는 확장 문자 역슬래시 다음에 일반 문자가 오면 특수문자로 취급하고 역슬래시 다음에 특수문자가 오면 그 문자 자체를 의미 |
(?i) | 앞 부분에 (?i) 라는 옵션을 넣어주면 대소문자를 구분하지 않음 |
volatile 키워드는 멀티thread시에 도움이 된다.
1. 읽고 쓰기에 대한 원자성. ( byte단위의 원자화는 보장함. alignment는 맞춰줌. )
2. 컴파일러의 임의 리오더링을 방지.
반면,
synchronized는 블록으로 묶인 부분 혹은 변수를 원자화(makes atomic ) 함.
<Wikipedia singleTon 예제>
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class){
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
ForkJoinPool 과 ThreadPoolExecutor 이 대표적으로 ExecutorService를 구현한 class 이다.
Executor<-ExecutorService관계이며, Excutor가 Runnable를 실행하고, ExecutorService 에서 shutdown등으로 관리가능.
(이렇게 Factory 형태로도 많이 쓰인다)
ExecutorService pool = Executors(유틸).newFixedThreadPool (thread num) returns ExecutorSerivce.
=> newFixedThreadPool을 이용한 서버소켓 accept 예제.
pool.execute ( request ); //Executor REF
pool.shutdown() or submit() or blabla; //ExecutorService
==> 참고2 사이트: pool.submit (Callable )으로 실행되지만, 실제 Callable.call이 언제실행될지 모르므로
Executor은 Future를 리턴. future . get() : (blocking임)으로 값가져 옴.
=============ForkJoin Pool==========
ForkJoinPool에 RecursiveAction구현 객체를 invoke 하면
객체의 compute 함수가 실행되면서
compute 내에 구현된 InvokeAll(work1,work2)를 통해 멀티코어를 실행하게 된다.
<<< Factorial을 이용한 ForkJoinPool 예제 >>
public class TestPool {
public static void main(String[] args){
ForkJoinPool pool = new ForkJoinPool();
long time1 = System.currentTimeMillis();
for(int i=0; i<500000;i++){
MyWork myWork = new MyWork(25); //25factorial
pool.invoke(myWork);
}
long time2 = System.currentTimeMillis();
System.out.println("Elapse:" + (time2-time1));
}
}
class MyWork extends RecursiveAction{
int base=0;
int to=1;
long result=1;
//factorial
public MyWork(int base){
this.base = base;
}
//half factorial
public MyWork(int base, int to){
this.base = base;
this.to = to;
}
@Override
protected void compute() {
//////small value Calculate and return
if ( base-to <= 2 ){
System.out.println("END: base,to:" + base +","+to);
for ( int i=base; i >= to; i-- )
result = result*i;
return;
}
//////large value DIVIDE as 2 works.///////////////
int median = to+ (base-to)/2;
MyWork w1 = new MyWork(base, median+1);
MyWork w2 = new MyWork(median, to);
invokeAll( w1, w2); //waiting.... then why USE RecursiveTask(which resturns VALUE)
result = w1.result * w2.result;
System.out.println("FINAL RESULT:" + result);
}
}
<JDK 1.4>
(Selectable)Channel
has
Selector
has
SelectionKey 인데 Selector를 서버채널과 클라이언트 채널에 동시에 등록해 accept와 read동시 수행 가능.
<JDK1.6 >의
java.nio.channels.SelectorProvider 는 linux시스템의 epoll을 구현. select=O(n), epoll=O(1)
nio = non-blocking io 임.
=========Selector 예제===== 서버 thread=====
//nio version
public void run(){
ServerSocketChannel ssc=null;
try{
//for SSC
InetSocketAddress addr = new InetSocketAddress(1990);
ssc = ServerSocketChannel.open();
ssc.socket().bind(addr);
//for Selector
Selector selector=Selector.open();
ssc.configureBlocking(false); //make nonBlocking accept()
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true){ //select for accept While
int numKeys = selector.select(); //select is non Blocking.
if (numKeys > 0){
//System.out.print(" numKeys:" + numKeys); //too much call
Set<SelectionKey> keySet = selector.selectedKeys(); /// Must be selectedKeys.
Iterator<SelectionKey> it = keySet.iterator();
while( it.hasNext()) {
SelectionKey key = it.next();
if( (key.readyOps() & SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){
SocketChannel csc = ((ServerSocketChannel) key.channel()).accept();
csc.configureBlocking(false);
System.out.println(" [Server] Client Connected ------"+csc);
//read Key register
csc.register(selector, SelectionKey.OP_READ);
it.remove();//delete key
}else if( (key.readyOps() & SelectionKey.OP_READ)==SelectionKey.OP_READ){
SocketChannel csc = (SocketChannel) key.channel();
//System.out.println(" [Server] Client READ Event ------"+csc);
readFromClient(csc);
it.remove();//delete key
}
}
}
Thread.sleep(10);
} //while
}catch (Exception e){
e.printStackTrace();
}finally{
try{
if(ssc!=null) ssc.close();
}catch (IOException e){}
}
}//run
Generics: - casting으로부터의 해방.
List<String>,
List<?> ?: any type extends Object
Class<?> : (Object).getClass()로 리턴되는 특정 class의 정보 집합.
JMX도 추가. (JMX등 JEE 참고사이트 )
java.util.Concurrent
- Executor가 대표적: 멀티코어 활용.
그러나, 일반적인 thread프로그래밍 만으로도 (green thread = single thread OS)가
아닌 이상은 멀티코어가 어느정도 적용된다고 함.
그 외
http://skycris.tistory.com/3 1.5에 추가된
boxing/unboxing, - int(원시 형)과 Integer간 자동 형변환.
static import,
annotation 설명
레퍼런스: http://javacan.tistory.com/tag/nio
속도가 향상된 nio(new io)는 기존 java라기 보단 c코드라고 봐야할 것 같다.
DirectBuffer가 속도가 빠르고, IndirectBuffer는 임시용.
Buffer는 보통 Channel(c언어로 된 Stream이라고 보면 될듯) 과 함께 써야 함.
ByteBuffer buf = ByteBuffer.allocateDirect(8);
buf.putByte( (byte)0xAB );
buf.putShort( (short)0xCDEF );
이렇게 하면, buf에 position=3, limit=8=capacity 이 됨.
buf.rewind : p=0.
buf.clear() : p=0, l=8 (초기상태)
buf.flip() : p=0, limit=3(현재위치)
뭔가 write한 후에는 남은 byte를 맨 앞으로 옮겨주는
buf.compact() 필요. 주로 buf.isRemaining()과 함께 쓰이는 듯.
<<실제 예제>>
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
FileIntputStream is = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(dest);
inputChannel = is.getChannel();
outputChannel = out.getChannel();
} catch(IOException ex) {
ByteBuffer buffer = ByteBuffer.allocateDirect(512);
int len ;
while ( (len = inputChannel.read(buffer)) != -1) {
buffer.flip(); //뒤쪽 limit을 마킹. 즉 limit=position, position=0이 됨
outputChannel.write(buffer); //읽은거 그대로 write.
buffer.clear(); //p=0, limit=512가 됨.
}
<<짧은 파일을 RandomAccess -> MappedByteBuffer (Direct임) 로 매핑해서.. 파일의 내용을 꺼꾸로 하기..>>
RandomAccessFile ra = new RandomAccessFile("/hello.txt","rw");
FileChannel fc = ra.getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE,0, ra.length());
int len = ra.length();
RandomAccessFile ra = new RandomAccessFile("/hello.txt","rw");
FileChannel fc = ra.getChannel();
//파일을 파일 채널을 이용하여 버퍼에 매핑 합니다.
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE,0, ra.length());
int len2 = (int)ra.length();
//파일 자체 내용을 뒤집기
for (int i = 0, j = len2 - 1; i < j; i++, j--)
{
byte b = mbb.get(i);
mbb.put(i, mbb.get(j)); //파일의 내용을 순서 바꿉니다.
mbb.put(j, b);
}
fc.close();