2009-03-25 4 views
14

자주 사용하는 개체 풀을 유지 관리하고 새 개체를 만드는 대신 풀에서 개체를 가져 오는 것은 무엇입니까? 그것은 모든 클래스 객체가 가능할 것이라는 점을 제외하면 string international과 같은 것입니다.개체 풀링

예를 들어 gc 시간과 개체 생성 시간을 절약 할 수 있으므로 좋은 것으로 간주 할 수 있습니다. 반면에 여러 스레드에서 사용되는 경우 동기화 병목 현상이 발생할 수 있으며 명시 적 할당 해제가 필요하며 메모리 누수가 발생할 수 있습니다. 매립 될 수있는 메모리를 묶음으로써 가비지 컬렉터에 추가적인 압력을 가하게됩니다.

+0

의견이 부정적으로 보입니다. 비슷한 것을 고려하고 있었다. 나는 수천 개의 작은 잠복 상자 객체를 만드는 J2ME 애플리케이션을 가지고있다. 내가 그 풀을 만들 수 있다면 나중에 GC에 더 쉬운 일을하게 할 것입니다. 이것이 휴대 전화의 제약 된 세계에서 여전히 나쁜 생각인지 궁금합니다. – izb

+0

값 비싼 객체 만 풀링합니다 (데이터베이스 연결 등). "비싼"의 정의는 요구 사항에 따라 크게 달라집니다. –

답변

18

개체를 만드는 데 비용이 많이 드는 경우가 아니라면 걱정하지 않으셔도됩니다.

장점 : 생성

  • 적은 객체 - 객체 생성 비싼 경우,이 중요 할 수 있습니다.

단점 ("창조", 인증 등을 제공하는 서버로의 네트워크 접속을 포함한다 정규 예, 아마 데이터베이스 연결이다)

  • 더 복잡한 코드
  • 공유 자원 = 잠금; 잠재적 인 병목 현상
  • 객체 수명의 GC의 기대 (단명됩니다 대부분의 개체)

당신이 해결하기 위해 노력하고 실제 문제가 있습니까을 위반하거나 투기인가? 당신이 벤치마킹/프로필을 가지고 있지 않으면 문제가 있다는 것을 보여주지 않는 한 이런 식으로 생각하지 않을 것입니다.

+0

대기 시간에 민감한 실시간 응용 프로그램에서 세계 정상 가비지 수집기라고 말하면서 막힘을 줄이는 데 정말로 관심이 있습니다. – baskin

+0

글쎄, 당신은 실시간 자바를 볼 수있다. 나는 직접 사용하지 않았지만, 점검 할만한 가치가있다. GC 튜닝도 시도해보십시오. 거기에는 많은 옵션이 있습니다. 물론 코드가 지연 시간에 민감한 비트 내에 * 어떤 * 객체도 할당하지 않도록 할 수 있다면 훌륭합니다.하지만 어렵습니다. –

+0

예, Java RTS를 살펴 보았습니다. 그러나 주로 RTS를 사용하지 않는 경향이 있습니다. GC 튜닝 또한 제가 시도해 본 것입니다. 특히 CMS gc로 놀아보십시오. 그게 바로 내가 최적의 최적의 매개 변수 조합을 치는 것이 아니라는 것입니다. 도움 주신 모든 분들께 감사드립니다. – baskin

2

나는 개체 수영장을 만들 특별한 이유가 없다면 Jon Skeet의 견해에 동의한다. 나는 신경 쓰지 않을 것이다.

풀이 실제로 도움이되거나 필요한 경우가 있습니다. 리소스를 생성하는 데 비용이 많이 들고 재사용 할 수있는 리소스가있는 경우 (예 : 데이터베이스 연결) 풀을 사용하는 것이 좋습니다. 또한 데이터베이스 연결의 경우 풀은 앱이 데이터베이스에 너무 많은 동시 연결을 열지 못하게하는 데 유용합니다.

21

첫 번째 최적화 법칙 :하지 마십시오. 두 번째 법칙 : 실제로 최적화하고 어디에서해야하는지에 대한 사실을 측정하고 알지 않는 한 그렇게하지 마십시오.

오브젝트를 작성하는 데 실제로 비용이 많이 들며 실제로 재사용 할 수있는 경우 (공용 조작만으로 상태를 재사용 할 수있는 것으로 재설정 할 수있는 경우) 효과적 일 수 있습니다.

당신이 언급 한 두 가지 이득은 사실이 아닙니다. java의 메모리 할당은 입니다.입니다 (비용은 10 cpu 명령에 가깝지만 아무 것도 없음). 따라서 객체 생성을 줄이면 생성자에서 소비하는 시간 만 절약됩니다. 이것은 변경없이 재사용 할 수있는 매우 무거운 객체 (데이터베이스 연결, 스레드)로 얻을 수 있습니다. 동일한 연결 (동일한 스레드)을 다시 사용합니다.

GC 시간이 줄어들지 않습니다. 사실 그것은 더 나쁠 수 있습니다. 움직이는 세대 GC (Java는 1.5까지)에서 GC 실행 비용은 릴리스 된 메모리가 아닌 살아있는 객체의 수에 의해 결정됩니다.Alive 객체는 메모리의 다른 공간으로 이동합니다 (메모리 할당 속도가 빨라짐 : 여유 메모리가 각 GC 블록 내에서 연속적입니다). 으로 표시되고 이전 세대 메모리 공간으로 옮겨지기까지 몇 번.

프로그래밍 언어 및 지원은 GC와 같이 일반적인 사용법을 염두에두고 설계되었습니다. 많은 경우에 일반적인 사용법을 벗어나면 코드를 읽는 것이 더 효율적이지 않을 수 있습니다.

+0

나는 실제로 대기 시간에 민감한 실시간 응용 프로그램에서 세계를 가비지 컬렉터라고 말하는 것으로 모든 막힘을 낮추는 데 관심이 있습니다. 당신이 말하는 것은 많은 의미가 있으며 나는 그런 결정을 내리는 데 벤치 마크가 필요하다는 데 동의합니다. – baskin

+2

GC 시간 *을 줄일 수 있습니다. 예를 들어 풀을 사용하면 대기 시간이 짧은 앱에서 중요한 이점을 얻을 수있는 등 개체를 할당해야하는 번거 로움을 피할 수 있습니다. 비록 당신이 결코 할당하지 못하도록하는 것이 진정한 고통입니다 ... –

+0

(나는 또한 GC 시간을 더 쉽게 악화시킬 수 있다고 동의합니다.) –

5

하지 마십시오.

이것은 2001 년 생각입니다. 아직 아무 것도 가치가없는 유일한 개체 "풀"은 싱글 톤입니다. 프로파일 링을 위해 객체 생성을 줄이기 위해서만 싱글 톤을 사용합니다 (그래서 코드에 어떤 영향을 미치는지 더 명확하게 볼 수 있습니다).

다른 용도로는 메모리를 조각 나고있는 것이 전부입니다.

1,000,000 개의 개체 생성시 프로필을 실행하십시오. 그것은 중요하지 않습니다.

Old article here.

+1

post-constructor 초기화 시간이 중요하지 않다는 것을 감안할 때 중요하지 않습니다. –

9

풀링은, 일반적으로, 객체는 불변 할 수 없음을 의미합니다. 이것은 디펜 시브 복사로 이어 지므로 궁극적으로 새로운 불변 ​​오브젝트를 만든 것보다 더 많은 복사본을 만들게됩니다.

불변성이 항상 바람직한 것은 아니지만 더 자주 발생하는 경우 불변 일 수 있습니다. 그것들을 불변으로 만들지 않아서 수영장에서 그들을 재사용 할 수 있다는 것은 좋은 생각이 아닙니다.

그렇다면 문제가 아니라는 것을 확실하게 알지 못한다면 걱정할 필요가 없습니다. 코드를 명확하고 쉽게 따르고 확률이 충분히 빠를 것입니다. 그것이 아니라면 코드가 명확하고 따르기 쉽기 때문에 (일반적으로) 속도를 높이는 것이 더 쉬울 것입니다.

+1

+1 내 고통을 아는 데. 개체 풀을 제거하여 심각한 데이터 손상 버그를 해결했습니다. 자바 1.3과 1.4의 프로파일 링은 풀을 큰 승리로 보여 주었다. 1.5에서는 코드가 느려졌다. – Darron

+0

당신이 무엇을 둬야하는지에 달려 있습니다. –

5

개체를 만드는 데 드는 비용이 얼마나 많은가에 달려 있습니다. ... 예를 들어 객체가 단지 영광스러운 구조체 인 경우 (예 : 두 개의 필드 만 포함하고 접근 자 이외의 메소드)는 풀링을위한 실제 사용 사례가 될 수 있습니다.

실제 예 : 많은 수의 정수/순위 쌍을 생성하는 프로세스에서 최상위 순위 항목 (정수)을 반복적으로 추출해야했습니다. 한정된 우선 순위 대기열에서 "쌍"객체 (정수 및 부동 소수점 순위 값)를 사용했습니다. 페어를 재사용하거나 대기열을 비우는 것, 페어를 버리고 재현하는 것은 JVM의 전체 수명 동안 페어를 재 할당 할 필요가 없었기 때문에 주로 GC 비용에서 20 %의 성능 향상을 가져 왔습니다.

3

개체 풀은 일반적으로 데이터베이스 연결과 같은 값 비싼 개체에만 적합합니다. Java 1.4.2까지 객체 풀은 성능을 향상시킬 수 있었지만 Java 5.0 객체 풀의 경우 도움말보다 성능에 해를 입히고 객체 풀이 제거되어 성능과 단순성을 향상 시켰습니다