Ubuntu Command Line으로 wifi 접속하기
sudo service network-manager restart
해주면된다.
sudo service network-manager restart
해주면된다.
LinkedList.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | public class LinkedList { private Node head; private Node tail; private int size = 0; private class Node { private Object data; private Node next; // 변수타입을 가지고 있어야함 public Node(Object input) { this.data = input; this.next = null; } public String toString() { return String.valueOf(this.data); } } // 머리에다가 추 public void addFirst(Object input) { Node newNode = new Node(input); newNode.next = head; head = newNode;// 방금 생성한 노드를 head로 size++; // 다음노드가 존재하지 않는다는 if (head.next == null) { tail = head; } } public void addLast(Object input) { Node newNode = new Node(input); if (size == 0) { addFirst(input); } else { tail.next = newNode; tail = newNode; size++; } } // 내부적으로 사용할것 (test를 위해 public) Node node(int index) { // 첫번째 노드를 찾아오는 것이고 그게 헤드이다. Node x = head; // 다음 노드들을 가지고 오기 위해서 next를 인덱스만큼 반복 for (int i = 0; i < index; i++) { x = x.next; } return x; } public void add(int k, Object input) { if (k == 0) { addFirst(input); } else { // 추가시키지 이전 노드를 알고있어야함 Node temp1 = node(k - 1); // 밀어질 노드에 대한 정보 Node temp2 = temp1.next; Node newNode = new Node(input); temp1.next = newNode; newNode.next = temp2; size++; // 뒤에 널이면 테일로 바준닷. if (newNode.next == null) { tail = newNode; } } } public String toString() { if (head == null) { return "[]"; } Node temp = head; String str = "["; while (temp.next != null) { str += temp.data + ","; temp = temp.next; } str += temp.data; return str + "]"; } // 자바에서는 컬렉션 프레임웍은 삭제된 노드의 값을 리턴해주게된다. public Object removeFirst() { Node temp = head; head = head.next; Object returnData = temp.data; temp = null; size--; return returnData; } // 노드 삭제하기 public Object remove(int k) { if (k == 0) { return removeFirst(); } Node temp = node(k - 1); Node todoDeleted = temp.next; temp.next = temp.next.next; Object returnData = todoDeleted.data; if (todoDeleted == tail) { tail = temp; } todoDeleted = null; size--; return returnData; } // 마지막 노드 삭제 테일만 지우면 이것저것 효과가 없어진닷; public Object removeLast() { return remove(size - 1); } // 사이즈 호출하기 public int size() { return size; } // 특정한 위치의 데이터 가져오기 public Object get(int k) { Node temp = node(k); return temp.data; } public int indexOf(Object data) { Node temp = head; int index = 0; while (temp.data != data) { temp = temp.next; index++; if (temp == null) { return -1; } } return index; } public ListIterator listIterator() { return new ListIterator(); } public class ListIterator { private Node next; private Node lastReturned; // 몇번째 있는가 알필요가 있고, hasNext할때 필 private int nextIndex; ListIterator() { next = head; } public Object next() { lastReturned = next; next = next.next; nextIndex++; return lastReturned.data; } public boolean hasNext() { return nextIndex < size(); } public void add(Object input) { Node newNode = new Node(input); if (lastReturned == null) { head = newNode; newNode.next = next; } else { lastReturned.next = newNode; newNode.next = next; } lastReturned = newNode; nextIndex++; size++; } public void remove() { if(nextIndex == 0) { throw new IllegalStateException(); } //비효율적이다. 노드를 찾았는데또 찾음!; LinkedList.this.remove(nextIndex-1); nextIndex--; } } } | cs |
Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | public class Main { public static void main(String[] args) { LinkedList numbers = new LinkedList(); // numbers.addFirst(30); // numbers.addFirst(20); // numbers.addFirst(10); // numbers.addLast(10); numbers.addLast(20); numbers.addLast(30); // numbers.add(1, 15); // numbers.removeFirst(); //특정한위치에 // numbers.add(2,25);// 20은 뒤로밀린다. // System.out.println(numbers); //head삭 // System.out.println(numbers.removeFirst()); // System.out.println(numbers); // System.out.println(numbers.remove(0)); // System.out.println(numbers.size()); // System.out.println(numbers.get(2)); // System.out.println(numbers.indexOf(30)); LinkedList.ListIterator i = numbers.listIterator(); // System.out.println(i.next()); // System.out.println(i.hasNext()); // System.out.println(numbers.node(2)); //hasNext호출을 위한 메소드 // while(i.hasNext()) { // System.out.println(i.next()); // } //head에 노드 추가하 // i.add(5); // i.next(); // 중간에 노드 추가하기 // i.add(15); // System.out.print(numbers); i.next(); i.remove(); } } | cs |
Java9 발표에 대한 요약 (0) | 2017.11.06 |
---|---|
GC(가비지 콜렉션)에 대한 공부 (0) | 2017.11.03 |
출저: pop it의 심천보님
잘 정리가 되어있는 글을 읽고, 공유하게 되었습니다.
이번 발표에 대한 가장 충격이었던 부분은 'var 지원'이였습니다. 뭔가 어색하네요 ,
한번 다들 읽어보셔요 !
Linked List (단순 연결 리스트) 소스 (0) | 2017.11.10 |
---|---|
GC(가비지 콜렉션)에 대한 공부 (0) | 2017.11.03 |
취업준비를 하면서 내가 제대로 보지 못했던 자바의 '진짜 모습'을 보고자 노력하고 있다. 그래서 첫번째로, GC에대해서 살펴 볼 것이다.
자바를 공부하면서 흥미로웠던 것은 GC였다. 하지만, 학교내의 프로젝트에서는 GC를 보기 힘들다. 이번기회를 통해 GC를 튜닝하는 방법까지 공부하면서 구현할 예정이다.
가비지 컬렉션(GC)
말그대로 '쓰레기 수집가'이다. 하지만 그냥 수집가가 아니다, GC는 프로그램의 성능과도 연결될 수 있다. 그만큼 GC는 자바의 필수적인 요소이다.
Stop-the-world
이 용어의 뜻은 나는 이렇게 이해했다. 모두 멈추고 어둠의 지배자인 GC의 활동(?).. 이해하기 위해서 이렇게 생각했었다. GC를 진행하는 쓰레드를 제외하고 모든 쓰레드가 멈춘후, GC가 작업을 완료하면 중단한 작업들을 다시 시작한다, 라는 용어이다. 생각해보면 멈춘시간이 짧을 수록 좋은 프로그램이 아닐까 생각든다. 그렇기때문에 GC튜닝과정에서는 이 시간을 줄이는 것이다.
자바는 명시적으로 프로그램을 지정하여 해제 하지 않는다
그렇다. 그러지 않는다, 명시적으로 해제하지 않고 가비지 컬렉터가 필요없는 객체들을 찾아 치우는 작업을 한다. 하고 싶다면 null로 지정하거나, system.gc()를 호출하는데 후자는 절대로 하면 안된다.(성능에 무리)
weak generational hypothesis
가비지 컬렉터는 이 가설을 바탕으로 만들어 졌는데 ,
이 가설을 전제조건으로 가비지 콜렉터가 만들어졌다.
2개의 공간 Young and Old
위 가설의 장점을 살리기 위해 2개의 물리적 공간으로 나뉘는데 ,
Young과 Old이다.
Young 영역
Order 영역
추가적으로 perm영역이 있다. java 8에서는 사라졌다고 들었다, 아니 대체되었다는 표현이 정확하겠다. 이 영역에서는 객체or억류된 문자열이 저장된다. Old영역에서 살아남은 객체가 영원히 남아있는 것은 아니다. GC가 발생할 수 있고 Major GC라한다.
Old영역에 있는 객체가 Young 영역의 객체를 참조하는 경우의 처리
카드 테이블을 이용한다. 카드테이블의 크기는 512Byte이다. Old영역에 있는 객체가 Young영역의 객체를 참조할때마다 카드테이블에 표시를 해준다. 따라서 Young의 GC가 실행되면 Old영역이 아닌 카드테이블을 이용하여 처리한다. write barrier를 사용하며 관리하고 minor gc빠르게 해준다. 약간의 오버헤드의 위험이 있지만, 전반적인 GC시간은 줄어든다.
Young generation
제일 먼재 객체가 생성되어 저장되는 곳이다 , 3개의 영역으로 나뉘는데
Eden 과 두개의 Survivor이다.
두 개의 Survivor중 반드시 하나는 비어있어야한다. 둘다 아무것도 없거나, 둘다 있으면 시스템은 정상이 아니다.
빠른 메모리 할당을 위한 기술이 있다.
bump-the-pointer
Eden의 가장 높은(top)부분에는 마지막 객체가 존재한다. bump-the-pointer는 새로운 객체가 생성되면
이 객체가 Eden에 들어가도 되는지 검사를 한다. 그리고 검사를 통과한 객체는 Top위치로 가게 된다.
이러한 이유로 객체를 생성할때 마지막에 추가된 객체만 점검하면된다. 때문에 메모리 할당이 매우 빠르게 된다.
하지만..!
멀티 쓰레드 상황에서는 Thread-safe를 위해 여러 스레드에서 Eden영역을 사용할때에는 롹이 발생한다.
그렇게 되면 성능은 떨어질 가능성이 있다. (..lock contention)
Thread-Local-Allocation-Buffers(TLABs)
각 스레드마다 Eden영역의 작은 덩어리를 나눠준다. 그렇기 때문에 각 스레드는 자신의 TLABs에만 접근하면 된다.
이렇게 롹이 발생할 가능성을 없앨 수 있다.
Old 영역의 GC
Old Generation에 객체가 가득차면 실행하게된다.
Old영역에서 사용하는 알고리즘이다.
Mark : Old영역에 살아있는 객체를 식별한다.
Sweep : 힙의 앞부분부터 확인하여 살아있는것만 남긴다.
Compaction : 앞부분부터 채워서 객체가 존재하는 구역과 존재하지 않는 구역을 나눔
#Parallel Old GC
Parallel GC와 비교하여 Old영역의 GC만 다름
mark-summary-Compaction 단계를 거침
별도로 살아있는 객체를 식별한다는 점에서 더 복잡해짐
-XX:+UseParallelOldGc 로 활성화
Linked List (단순 연결 리스트) 소스 (0) | 2017.11.10 |
---|---|
Java9 발표에 대한 요약 (0) | 2017.11.06 |