C언어에서 제공하는 atoi 메서드를 자바로 구현해보자.


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
public class Main {
 
    public static void main(String args[]) {
        atoi("20");
    }
    
    public static int atoi(String str) {
        
        int radix = 10;
        
        byte[] temp = str.getBytes();
        int result = 0;
        for(int i=0;i<temp.length;i++) {    
            if (temp[i] < '0' || temp[i] > '9') { // 0~9 넘어갈경우 (문자 방지)
                throw new NumberFormatException();
            }
            result = (result*radix) + temp[i] - '0';
            System.out.printf("(%s*%s) + %s - '0'", result, radix, temp[i]);
            System.out.println();
        }    
        
        return result;
    }
    
}
 
cs


계산과정

(2*10) + 50 - '0'

(20*10) + 48 - '0'


temp[i]가 0 ~ 9 사이를 넘어서는 경우에는 숫자가 아니라고 판단되어 오류를 미리 발생한다.


자바에는 크게 4개의 List 인터페이스를 구현한 클래스가 있다.

- Vector, ArrayList, LinkedList, CopyOnWriteArrayList


그 중 가장 생소한 이름이 있는데 CopyOnWriteArrayList이다. CopyOnWriteArrayList는 그냥 ArrayList랑 다르길래 화려한 이름을 가지고 있는걸까?


ArrayList vs CopyOnWriteArrayList

일반 ArrayList의 경우 스레드에 안전하게 설게되어 있지 않기때문에 만약 스레드 처리가 필요한 List의 경우에 Vector를 사용하거나 ArrayList에 synchroized를 사용하여 처리하였다. 하지만 자바 1.5부터 있던 CopyOnWriteArrayList를 쉽게 이문제를 해결할 수 있다.


CopyOnWriteArrayList의 경우 ArrayList와 모든 부분이 동일하나 어디에 컨텐츠를 전달할 때 컨텐츠를 복사해서 전달한다. 그렇기 때문에 전달 후 해당 List의 내용이 변경될 것을 우려하지 않아도 된다.


CopyOnWriteArrayList는 그냥 ArrayList보다 물론 부담이 있을수 있다. 하지만 잘못설계된 동기화코드보다 더 안전하고 비용이 절감될 수도 있다.


그리고 CopyOnWriteArrayList는 객체를 매번 복사하는 것이 아니라 전달시 해당 상태를 스냅샷으로 가지고 있는 방식으로 진행한다.

자세한 내용은 아래 사이트를 참조하면 도움이 될 것이다.


https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

자바 메모리 누수 측정 방법

  • 자바 프로그램의 실제 메로리 사용량은 시스템의 작업관리자에서 나오는 메모리 사용량으로는 측정  없기에 디버그 출력으로 totalMemory() - freeMemory() 출력하거나개발 도구를 사용하여 측정하는 것이좋다.

 

GC 알고리즘

  • 메모리가 GC 부터 해소가 되지 않는 루트 참조 객체(직간접적으로 참조가 되는 모드 객체) 크게 3가지경우이다.
  1. Static 변수에 의한 객체 참조
  2. 모든 현재 자바 스레드 스택내의 지역 변수매개 변수에 의한 객체 참조
  3. JNI 프로그램에 의해 동적으로 만들어지고 제거되는 JNI global 객체 참조

이러한 경우에 사용할  있는 객체로 분류되어 GC에서 가져가지 않아 메모리가 누수될  있다.


자바 메모리영역은 3가지로 구성되어 있다.

Heap : 사용자가 생성하는 object

Metaspace : classload, 메소드변수 정보를 저장하는 영역

Native : OS 자원을 보관하는 영역

HashMap 저장되어 있는  값을 통해 저장된 value 값을 찾을 입력된 object 동일한 hashCode 값을 가지고 있는키를 찾기 위해  객체에 정의된 equals 메소드를 사용한다.

 

 개의 object  정의한 equals 통해 비교한  동일한 객체  경우 동일한 hashCode값을 반환한다.

 

그렇기에 instance 객체를 hashMap key값으로 사용하고 싶은 경우에는 비교에 사용되는 equals() 동일한 객체에 대한 동일한 hashCode 값을 반환하는 hashCode() 메소드를 Override 해야한다.

 

 참고자료




https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.KeySetView.html

http://www.javamex.com/tutorials/collections/hash_code_equals.shtml

https://en.wikipedia.org/wiki/Java_hashCode()


실제로 진행중인 프로젝트에서


다음과 같은 상황이 있었다.


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
public class Person {
 
private int id;
 
private String name;
 
 
 
public Person(int id, String name) {
 
this.id = id;
 
this.name = name;
 
}
 
 
 
@Override
 
public boolean equals(Object obj) {
 
return this == obj || (this.id == obj.id && this.name.equals(obj.name);
 
}
 
}
 
 
 
private static final HashMap<Person, String> map = new HashMap<Person, String>(); 
 
 
 
public static void main(String[] args) {
 
Person A = new Person(1'babo');
 
map.put(A, 'is you');
 
 
 
String str = null;
 
str = map.get(new Person(1'babo'));
 
 
 
if (str == null) {
 
System.out.println("omg");
 
}
 
}
 
 
 
Result
 
=> omg
cs



위에 내용은 블로그에서 직접 약식으로 만든 것이라 대충 보면 될 것 같다.


문제 상황은 위에서 hashMap의 키 값으로 입력한 Person 인스턴스 객체를 


다시 찾으려고 동일한 값을 가진 Person객체를 삽입 하였으나


map에서 value를 받아오지 못했다.


그 이유는 Person 클래스에 equals() 메소드는 정의 하였으나, 동일한 객체면 동일한 hashCode 값이 반환되도록


hashCode() 메소드를 재 정의 하지 않았기 때문이다.


그래서 map에서는 두개의 객체가 서로 다른 hashCode 값을 반환하는 다른 객체로 보았기 때문에 value를 반환하지 못했다.


결론은 클래스를 정의할 때는 equals()를 재 정의해서 사용할 때, hashCode()도 같이 재정의 할것!

자바에서 Annotation은 별도의 properties파일이나 xml같은 설정파일에 작성하는 부가적인 정보를 어노테이션으로 간편하게 설정할 수 있다.


형태


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Target(ElementType.TYPE)
 
@Retention(RetentionPolicy.RUNTIME)
 
@Documented
 
public @interface Anno {
 
 public String defaultVal()  default “OK”;
 
 public String val();
 
}
 
 
cs



Target은 어노테이션의 적용 대상을 선정하고, Retension은 이 어노테이션의 정보가 어디 까지 유지되는지 설정한다.


@Target - Constructor, Field, Enum, Local Variable, Method, Package, Parameter, Type(Class)
@Retention - Source, Class, Runtime
@Documented - 어노테이션을 javadoc에 포함한다.
@Inherited - 어노테이션 상속을 가능케 한다.  

구현된 어노테이션 사용은 다음과 같이 사용한다.


 


1
2
3
4
5
6
7
8
9
10
@Anno(val = "Annotation!!"
public class Member { 
.....
}  
 
정의한 어노테이션에 대한 접근은 다음과 같다.
 
Member member = new Member(); 
System.out.println(member.getClass().getAnnotation(Anno.class).val()); 
System.out.println(member.getClass().getAnnotation(Anno.class).defaultVal());  
cs



참고 사이트 : http://blog.naver.com/cracker542/40159657935

+ Recent posts