달력

112018  이전 다음

  •  
  •  
  •  
  •  
  • 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
  •  


개인적으로 50만원이라는 거금을 들여서 꽤 오래전부터 JProfiler라는 상용 자바 프로파일러 제품을 사용하고 있습니다. 그동안 사용하면서 사용법은 이미 머리속에 있으나 간단히 정리를 해야 할거 같아 위키에 정리했습니다. 대부분 스크린샷만 둔거라 기존에 사용해보지 않으신 분은 알아보기 힘드시겠네요. T.T


◆ 기본기능 사용법


◆ JProfiler 6에서 부턴가 추가된 Probe 기능 살펴보기

Posted by 이동국

댓글을 달아 주세요


jprofiler 의 라이센스가 5.x 대라, 5.x 버전의 최신인 5.2.4를 사용하고 있다.
스냅샷 저장 및 열기 기능은 그닥 많이 사용하지는 않지만, 내부 리포트를 작성하기 위해서는 필수로 사용하게 되는 기능인데 에러가 발생한다.
분명 5.2.4 버전에서 스냅샷을 생성하고, 그 파일을 읽어들이는데도 에러가 발생해서 ej-technologies 에 메일을 보냈다. 언제 답변이 올런지..
Posted by 이동국

댓글을 달아 주세요

# 테스트 환경
1. jdk1.6.0_23
2. 프로파일러 : JProfiler v.5.2.4

# 케이스별 테스트 소스와 프로파일링 결과
1. 모델의 setter메서드로 셋팅
public static JaxbMessage validateUrlParam(BindingResult result) {
    if (result.hasErrors()) {
        JaxbMessage message = getDefaultMessage();
        LOGGER.info("바인딩결과 : {} ", result);

        JaxbError error = new JaxbError();
        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        error.setCode(errorCode);
        error.setMsg(ValidationErrorMessageAccessor.getMessages().get(errorCode));

        LOGGER.info("{}", error);

        message.setError(error);
        return message;
    }
    return null;
}


20번 호출에 15,653us 소요됨

2. Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 사용
public M validateUrlParamOld(M message, E error, String service, String type, String version, BindingResult result) {
    if (result.hasErrors()) {
        LOGGER.info("바인딩결과 : {} ", result);

        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        try {
            PropertyDescriptor[] errorPds = BeanUtils.getPropertyDescriptors(error.getClass());
            for (PropertyDescriptor desc : errorPds) {
                if ("code".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(error, errorCode);
                }
                if ("msg".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(error, ValidationErrorMessageAccessor.getMessages().get(errorCode));
                }
            }

            PropertyDescriptor[] messagePds = BeanUtils.getPropertyDescriptors(message.getClass());
            for (PropertyDescriptor desc : messagePds) {
                if ("error".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, error);
                }
                if ("service".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, service);
                }
                if ("type".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, type);
                }
                if ("version".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, version);
                }
            }
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        return message;
    }
    return null;
}


20번 호출에 21,372us 소요됨

3. Spring의 ReflectionUtils 사용
public M validateUrlParam(M message, E error, String service, String type, String version, BindingResult result) {
    if (result.hasErrors()) {
        LOGGER.info("바인딩결과 : {} ", result);

        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        try {
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setCode", String.class), error, errorCode);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setMsg", String.class), error,
                ValidationErrorMessageAccessor.getMessages().get(errorCode));

            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setError", error.getClass()), message, error);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setService", String.class), message, service);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setType", String.class), message, type);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setVersion", String.class), message, version);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        }

        return message;
    }
    return null;
}


20번 호출에 13,008us 소요됨

# 정리
1. 순수하게 JDK의 리플렉션을 사용한 테스트 수치는 없음
2. Spring
ReflectionUtils < 모델 setter 메서드 < Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 순으로 소요시간이 적음
3. 모델 setter 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨
Posted by 이동국

댓글을 달아 주세요


최근에 관심을 가지는 분야는 개발에 관련된 측정방법입니다.
측정이라고 하면 다양하게 있죠.. 이를테면 성능을 측정한다거나 소스코드 품질을 측정한다거나 다양한 측정요소가 있고 측정방법이 있습니다. 그만큼 측정을 도와주는 다양한 제품또한 나와 있습니다.
그런 맥락에서 작년에 구입했던 제품이 JProfiler 이죠..

최근 회사에서 담당한 것 중에 하나가 현재 출시되어 있는 프로파일러의 비교였습니다.
회사의 정책에 반하지 않는 범위내에서 리뷰 자료를 첨부합니다.

기본적으로 비교한 제품은 다음과 같습니다.
1. JProfiler 5.x
2. Yourkit Profiler 7.0
3. JProbe(<- 리뷰 자료는 없습니다. )
4. eclipse TPTP
5. netbeans profiler

개인적인 생각으로 제품의 순위는 상용제품의 경우 JProfiler -> Yourkit Profiler -> JProbe 순으로 JProfiler 의 기능이 만족스럽구요. 오픈소스인 TPTP와 netbeans profiler의 경우에는 장단점이 다르고 해당 IDE에 특화된 점 때문에 어느제품이 좋다고 논하기 힘들꺼 같습니다.

간단한 리뷰 자료라 생각보다 내용이 빈약할수 있고 개인적인 사견이 많이 들어 있습니다.
상세한 내용에 대해서는 다른 방식(메신져나 이메일..)을 통해 문의하시면 답변드릴수 있으리라 생각됩니다.
Posted by 이동국

댓글을 달아 주세요