https://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil
Why are static variables considered evil?
I am a Java programmer who is new to the corporate world. Recently I've developed an application using Groovy and Java. All through the code I wrote used quite a good number of statics. I was asked...
stackoverflow.com
static은 정적의 , 고정의 라는 뜻으로 static 으로 선언되면 프로그램이 종료되기 전까지 메모리를 차지한다.
전역변수처럼 상위에 고정되어 있다. 그래서 객체 생성 없이 꺼내서 사용하기에는 편리하나 관리하기가 불편하고
사용하지 않을 때 가비지로 수집되지 않아 메모리 누수가 발생할 수 있다.
객체들의 자율적인 협력을 지향하는 객체지향 프로그램에 맞지 않다.
위 글에서 다시 보려고 적어둔 내용!
Java에서 정적 메소드를 사용할 때의 몇 가지 기본적인 장점과 단점을 요약하면 다음과 같습니다.
장점:
- 전역적으로 액세스 가능합니다. 즉, 특정 개체 인스턴스와 연결되지 않습니다.
- JVM당 하나의 인스턴스입니다.
- 클래스 이름을 사용하여 접근할 수 있습니다(객체가 필요하지 않음).
- 모든 인스턴스에 적용할 수 있는 단일 값을 포함합니다.
- JVM 시작 시 로드되고 JVM이 종료되면 종료됩니다.
- 객체의 상태를 수정하지 않습니다.
단점:
- 정적 멤버는 사용 여부에 관계없이 항상 메모리의 일부입니다.
- 정적 변수의 생성과 소멸을 제어할 수 없습니다. 유용하게도 프로그램 로드 시 생성되고 프로그램 언로드 시(또는 JVM이 종료될 때) 삭제됩니다.
- 동기화를 사용하여 정적 스레드를 안전하게 만들 수 있지만 추가 노력이 필요합니다.
- 한 스레드가 다른 스레드의 기능을 중단시킬 수 있는 정적 변수의 값을 변경하는 경우.
- 사용하기 전에 "정적"을 알아야 합니다.
- 정적 메서드를 재정의할 수 없습니다.
- 직렬화가 제대로 작동하지 않습니다. (직렬화란? - 객체를 저장, 전송할 수 있는 바이트 스트림으로 변환하는 것 : 직렬화에 대한 설명 )
- 런타임 다형성에는 참여하지 않습니다.
- 많은 수의 정적 변수/메서드를 사용하는 경우 메모리 문제가 있습니다(어느 정도까지는 아니지만 그다지 많지는 않을 것 같습니다). 프로그램이 끝날 때까지 가비지 수집되지 않기 때문입니다.
- 정적 메서드도 테스트하기 어렵습니다.
정적 변수를 사용했을 시 나타나는 문제점
테스트 실행
정적은 일련의 단위 테스트를 함께 실행할 때(예: 지속적 통합 서버에서) 실제 문제를 일으킵니다. 한 테스트에서 다른 테스트까지 열려 있는 네트워크 소켓 개체의 정적 맵을 상상해 보세요. 첫 번째 테스트에서는 포트 8080에서 소켓을 열 수 있지만 테스트가 중단되면 맵을 지우는 것을 잊었습니다. 이제 두 번째 테스트가 시작되면 포트가 여전히 사용 중이므로 포트 8080에 대한 새 소켓을 생성하려고 하면 충돌이 발생할 가능성이 있습니다. 또한 정적 컬렉션의 소켓 참조가 제거되지 않고 (WeakHashMap을 제외하고) 가비지 수집 대상이 되지 않아 메모리 누수가 발생한다고 상상해 보세요.
이는 지나치게 일반화된 예이지만 대규모 시스템에서는 이 문제가 항상 발생합니다. 사람들은 동일한 JVM에서 소프트웨어를 반복적으로 시작하고 중지하는 단위 테스트를 생각하지 않지만 이는 소프트웨어 설계에 대한 좋은 테스트이며 고가용성을 향한 열망이 있다면 알아야 할 사항입니다.
미묘한 버그
스레드를 다룰 때는 정적 개체를 사용하여 데이터를 저장하는 것보다 스레드 시작 단계에서 초기화된 개체를 사용하는 것이 좋습니다. 이렇게 하면 스레드가 시작될 때마다 개체의 새 인스턴스(잠재적으로 새로운 구성 포함)가 생성되고 스레드의 한 인스턴스에서 다음 인스턴스로 데이터가 흘러나오는 것을 방지할 수 있습니다.
스레드가 종료되면 정적 개체가 재설정되거나 가비지 수집되지 않습니다. (정적 개체는 프로그램이 종료되어야 생명주기가 끝이 나기 때문에)"EmailCustomers"라는 스레드가 있고 스레드가 시작되면 이메일 주소 목록으로 정적 문자열 컬렉션을 채운 다음 각 주소에 이메일을 보내기 시작한다고 가정해 보세요. 스레드가 어떻게든 중단되거나 취소되어 고가용성 프레임워크가 스레드를 다시 시작한다고 가정해 보겠습니다. 그런 다음 스레드가 시작되면 고객 목록을 다시 로드합니다. 그러나 컬렉션은 정적이므로 이전 컬렉션의 이메일 주소 목록이 유지될 수 있습니다. 이제 일부 고객은 중복된 이메일을 받을 수 있습니다.
'자바' 카테고리의 다른 글
String 클래스의 equals() ,== 연산자, compareTo() 메소드 (0) | 2023.09.14 |
---|---|
인터페이스와 추상 클래스의 차이 (+왜 인터페이스의 변수는 static final로 선언될까 ? ) (0) | 2023.09.13 |
자바 4장을 마치며 인스턴스 변수와 클래스 변수의 차이를 알자~ (0) | 2023.08.30 |
자바의 신 3장을 마치며 클래스, 객체, 인스턴스, this연산자, 생성자 (2) | 2023.08.30 |
자바의 신 1, 2 장 마치며 (0) | 2023.08.30 |