Java 코드 사양을 통해 프로그램 최적화, 메모리 사용을 최적화하며 메모리 누출 방지
프로그램을 활용할 수있는 리소스 (메모리, CPU 시간, 네트워크 대역폭 등)는 최적화의 목적은 가능한 한 적은 자원으로 예약 된 작업을 완료 할 수 있도록하는 것입니다. 최적화에는 일반적으로 두 가지 측면이 포함됩니다. 코드의 크기를 줄이고 코드의 실행 효율을 향상시킵니다. 이 기사는 주로 코드의 효율성을 향상시키는 방법에 대해 설명합니다.
Java 프로그램에서는 성능 문제에 대한 대부분의 이유는 Java 언어가 아니라 프로그램 자체에 있습니다. 프로그램의 성능을 크게 향상시킬 수있는 java.lang.string class 및 java.util.vector 클래스를 올바르게 적용하는 것과 같은 좋은 코드 쓰기 습관을 개발하는 것이 매우 중요합니다. 이 문제를 아래에서 자세히 분석 해 봅시다.
1. 최종 수정자를 가진 클래스의 최종 수정자가 도출되지 않도록하십시오.
Java Core API에는 java.lang.string과 같은 최종 적용의 많은 예가 있습니다. 문자열 클래스에 최종을 지정하면 사람들이 length () 메소드를 덮어 쓰는 것을 방지합니다. 또한 클래스가 최종적으로 지정되면 해당 클래스의 모든 메소드는 최종입니다. Java 컴파일러는 모든 최종 방법을 인화 할 수있는 기회를 찾습니다 (이는 특정 컴파일러 구현과 관련이 있음). 이 움직임은 평균 50%증가한 성능을 향상시킬 수 있습니다.
2. 개체를 재사용하십시오.
특히 문자열 객체를 사용할 때 StringBuffer는 문자열 연결이 발생할 때 대신 사용됩니다. 시스템은 객체를 생성하는 데 시간이 걸릴뿐만 아니라 향후 이러한 물체를 수집하고 처리하는 데 시간이 걸릴 수 있습니다. 따라서 너무 많은 객체를 생성하면 프로그램 성능에 큰 영향을 미칩니다.
3. 로컬 변수를 사용하십시오. 메소드를 호출 할 때 통과 한 매개 변수와 통화에서 생성 된 임시 변수는 스택 (스택)에 저장됩니다.
정적 변수, 인스턴스 변수 등과 같은 다른 변수는 힙에 생성되며 느리게됩니다. 또한 특정 컴파일러/JVM에 따라 국소 변수가 추가로 최적화 될 수 있습니다. "가능할 때마다 스택 변수 사용"을 참조하십시오.
4. 변수 <br />의 초기화를 반복하지 않으면 기본적으로 클래스 생성자를 호출 할 때 Java는 변수를 특정 값으로 초기화합니다. Float 및 Double 변수는 0.0으로 설정되고 논리 값은 False로 설정됩니다. 클래스가 다른 클래스에서 파생 될 때 특히 새로운 키워드로 개체가 생성되면 생성자 체인의 모든 생성자가 자동으로 호출되므로 특히 알아야합니다.
5. Java + Oracle Application System의 개발에서 Java에서 대문자 형태를 사용하여 Oracle Parser의 구문 분석 부담을 줄입니다.
6. Java 프로그래밍 중에는 데이터베이스 연결 및 I/O 스트리밍 작업을 수행 할 때 조심하십시오.
이러한 큰 물체의 작동은 큰 시스템 오버 헤드를 유발하고 조심하지 않으면 심각한 결과를 초래할 것입니다.
7. JVM은 자체 GC 메커니즘을 가지고 있기 때문에 프로그램 개발자로부터 너무 많은 고려가 필요하지 않으므로 개발자의 부담이 어느 정도 줄어들면서 숨겨진 객체의 위험이 많이 있습니다. 시스템에서는 메모리 누출이 발생하므로 만료 된 객체를 적시에 재활용하는 것이 중요합니다 .
JVM이 쓰레기를 재활용하는 조건은 물체가 참조되지 않지만 JVM의 GC는 그다지 재치가 없으며 물체가 쓰레기 수집 조건을 충족하더라도 즉시 재활용되지 않습니다. 따라서 물체를 사용한 후 수동으로 NULL로 설정하는 것이 좋습니다.
8. 동기화 메커니즘을 사용할 때 코드 블록 동기화 대신 메서드 동기화를 사용하십시오.
9. 변수의 반복 계산 최소화 <br /> 예 : for (int i = 0; i <list.size; i ++) {
…
}
다음으로 대체해야합니다.
for (int i = 0, int len = list.size (); i <len; i ++) {
…
}
10. 게으른 적재 전략을 채택하십시오. 즉, 필요할 때 생성을 시작하십시오.
예를 들면 : 문자열 str =“aaa”;
if (i == 1) {
list.add (str);
}
다음으로 대체해야합니다.
if (i == 1) {
문자열 str =“aaa”;
list.add (str);
}
11.주의해서 이상을 사용하십시오
이상은 성능에 좋지 않습니다. 예외를 던지려면 먼저 새 개체를 만들어야합니다. Throwable 인터페이스의 생성자는 Fillinstacktrace ()라는 로컬 (기본) 메소드를 호출하고 FillinStackTrace () 메소드는 스택을 확인하고 통화 추적 정보를 수집합니다. 예외가 발생하는 한 처리 중에 새 개체가 생성되므로 VM은 통화 스택을 조정해야합니다. 예외는 오류 처리에만 사용될 수 있으며 프로그램 흐름을 제어하는 데 사용해서는 안됩니다.
12. 루프에서 사용하지 마십시오.
노력하다 {
} 잡다() {
}
가장 바깥 쪽 층에 배치해야합니다.
13. StringBuffer 사용 :
StringBuffer는 변수, 쓰기 가능한 문자열을 나타냅니다.
세 가지 시공 방법이 있습니다.
StringBuffer (); // 16 자 공간을 할당했습니다
StringBuffer (int size); // 크기에 공간을 할당합니다
StringBuffer (string str); // 16 자 + str.length () 문자 공간은 성능을 크게 향상시킬 수 있습니다.
여기에 언급 된 생성자는 StringBuffer (int length)이며 길이 매개 변수는 현재 StringBuffer가 보유 할 수있는 문자 수를 나타냅니다. StringBuffer 객체가 생성 된 후 EnseRecApacity (int minimum farent) 메소드를 사용하여 용량을 설정할 수도 있습니다. 먼저 StringBuffer의 기본 동작을 살펴보고 성능을 향상시키는 더 나은 방법을 찾으십시오.
StringBuffer는 내부적으로 캐릭터 배열을 유지합니다. 기본 생성자를 사용하여 StringBuffer 객체를 만들 때 StringBuffer의 용량은 16 자로 초기화됩니다. StringBuffer가 최대 용량에 도달하면 용량을 현재 용량의 2 배로 증가시키고 2, 즉 (2*Old Value +2)를 추가합니다. 기본값을 사용하면 초기화 후 문자를 추가하면 용량이 34 (2*16+2)로 추가되고 용량이 추가되면 용량이 증가합니다. ~ 70 (2*34+2). StringBuffer가 최대 용량에 도달하는 한 새로운 캐릭터 배열을 만들고 오래된 캐릭터와 새로운 캐릭터를 다시 코피해야합니다. 따라서 StringBuffer의 합리적인 초기화 용량 값을 항상 설정하는 것은 잘못된 것이 아닙니다. 이것은 StringBuffer 초기화 프로세스를 조정하는 역할을 보여줍니다. 따라서 적절한 용량 값을 사용하여 StringBuffer를 초기화하는 것은 항상 최적의 제안입니다.
14. Java 클래스 java.util.vector를 합리적으로 사용하십시오.
간단히 말해 벡터는 java.lang.object 인스턴스의 배열입니다. 벡터는 배열과 유사하며 정수 형태의 인덱스를 통해 요소에 액세스 할 수 있습니다. 그러나 벡터 유형의 객체를 생성 한 후, 요소의 첨가 또는 삭제에 따라 물체의 크기를 확장하고 감소시킬 수 있습니다. 벡터에 요소를 추가하는 다음 예를 고려하십시오.
개체 bj = new Object ();
벡터 v = 새로운 벡터 (100000);
(int i = 0;
i <100000; i ++) {v.add (0, obj);
매번 벡터 앞에 새로운 요소를 삽입 해야하는 충분한 이유가 없다면 위의 코드는 성능에 좋지 않습니다. 기본 생성자에서 벡터의 초기 저장 용량은 새로운 요소가 추가 될 때 저장 용량이 충분하지 않으면 향후 스토리지 용량이 두 배가됩니다. 벡터 클래스는 스토리지 용량이 확장 될 때마다 객체 StringBuffer 클래스와 같습니다. 다음 코드 스 니펫은 이전 예보다 훨씬 빠릅니다.
개체 bj = new Object ();
벡터 v = 새로운 벡터 (100000);
for (int i = 0; i <100000; i ++) {v.add (obj);
동일한 규칙이 벡터 클래스의 remove () 메소드에 적용됩니다. 벡터의 각 요소는 각 요소 사이에 "공간"을 포함 할 수 없으므로 마지막 요소를 제외한 다른 요소를 삭제하면 삭제 된 요소 후 요소가 앞으로 이동합니다. 즉, 벡터에서 마지막 요소를 삭제하는 것은 첫 번째 요소를 삭제하는 것보다 몇 배 덜 "오버 헤드"입니다.
이전 벡터에서 모든 요소를 제거하려고한다고 가정하면이 코드를 사용할 수 있습니다.
for (int i = 0; i <100000; i ++)
{
v.remove (0);
}
그러나 다음 코드와 비교하여 이전 코드는 순서가 느려집니다.
for (int i = 0; i <100000; i ++)
{
v.remove (v.size () -1);
}
유형 벡터의 객체 v에서 모든 요소를 삭제하는 가장 좋은 방법은 다음과 같습니다.
v.removeallelements ();
유형 벡터의 객체 v에 문자열 "Hello"가 포함되어 있다고 가정합니다. 이 벡터에서 "hello"문자열을 제거하는 다음 코드를 고려하십시오.
문자열 s = "hello";
int i = v.indexof (s);
if (i! = -1) v.remove (s);
코드는 잘못된 것처럼 보이지만 성능에도 좋지 않습니다. 이 코드에서는 indexof () 메소드가 v v를 검색하여 문자열 "hello"를 찾기 위해 v v를 검색하고 REMING (s) 메소드도 동일한 순서로 검색해야합니다. 개선 된 버전은 다음과 같습니다.
문자열 s = "hello";
int i = v.indexof (s);
if (i! = -1) v.remove (i);
이 버전에서는 remove () 메소드에서 삭제할 요소의 정확한 인덱스 위치를 직접 제공하여 두 번째 검색을 피합니다. 더 나은 버전은 다음과 같습니다.
문자열 s = "Hello";
마지막으로 벡터 클래스에 대한 코드 스 니펫을 살펴 보겠습니다.
for (int i = 0; i ++; i <v.length)
V에 100,000 요소가 포함되어 있으면이 코드 스 니펫은 v.size () 메소드를 100,000 번 호출합니다. 크기 메소드는 간단한 방법이지만 여전히 메소드 호출의 오버 헤드가 필요하지만 적어도 JVM은 스택 환경을 구성하고 지우아야합니다. 여기서 For Loop 내부의 코드는 벡터 유형 객체 v의 크기를 수정하지 않으므로 위의 코드는 다음 형식으로 가장 잘 다시 작성됩니다.
int size = v.size ();
이것은 간단한 변화이지만 여전히 성능을 얻습니다. 결국, 모든 CPU 사이클은 소중합니다.
15. 많은 양의 데이터를 복사 할 때 System.ArrayCopy () 명령을 사용하십시오.
16. 코드 리팩토링 : 코드의 가독성 향상 .
예를 들어:
Public Class ShopCart {private list carts;… public void add (객체 항목) {if (carts == null) {carts = new arrayList ();} crts.add (item);} public void remove (객체 항목) {if (carts. 포함 (항목)) {carts.remove (item);}} public list getCarts () {// return retud ord return collections.unmodifiablelist (carts);} //이 메소드는 권장되지 않습니다. getCarts (). add (item);} 17. 새 키워드를 사용하지 않고 클래스 인스턴스 생성
새 키워드가있는 클래스 인스턴스를 만들 때 생성자 체인의 모든 생성자가 자동으로 호출됩니다. 그러나 객체가 복제 가능한 인터페이스를 구현하면 클론 () 메소드를 호출 할 수 있습니다. 클론 () 메소드는 클래스 생성자를 호출하지 않습니다.
디자인 패턴을 사용하는 경우 팩토리 모드를 사용하여 객체를 만드는 경우 Clone () 메소드를 사용하여 새 개체 인스턴스를 만드는 것은 매우 간단합니다. 예를 들어, 다음은 공장 패턴의 일반적인 구현입니다.
공개 정적 크레딧 getNewCredit () {
새로운 크레디트 ()를 반환합니다.
}
개선 된 코드는 다음과 같이 clone () 메소드를 사용합니다.
개인 정적 신용 BaseCredit = New Credit ();
공개 정적 크레딧 getNewCredit () {
return (신용) basecredit.clone ();
}
위의 아이디어는 또한 배열 처리에 매우 유용합니다.
18. 곱셈 및 분열
다음 코드를 고려하십시오.
for (val = 0; val <100000; val += 5) {
alterx = val * 8;
}
곱셈을 시프트 작업으로 대체하면 성능이 크게 향상 될 수 있습니다. 수정 된 코드는 다음과 같습니다.
for (val = 0; val <100000; val += 5) {
alterx = val << 3;
}
수정 된 코드는 더 이상 8을 곱하지 않고 대신 3 비트의 동등한 왼쪽 시프트를 사용하며 왼쪽 당 1 비트에 2를 곱하는 것과 동등합니다. 따라서, 1 비트 작동에 의한 올바른 전환은 2로 나누는 것과 같습니다. 시프트 조작이 빠르지 만 코드를 이해하기 어려울 수 있으므로 몇 가지 의견을 추가하는 것이 가장 좋습니다.
19. JSP 페이지에서 쓸모없는 세션을 닫습니다.
일반적인 오해는 클라이언트 액세스가있을 때 세션이 생성된다는 것입니다 , <>를 닫으려면 JSP 파일이 서블릿에 컴파일되면이 명령문은 httpsession session = httpservletrequest.getsession (true)에 자동으로 추가됩니다. 세션은 메모리 리소스를 소비하기 때문에 세션을 사용하지 않을 경우 모든 JSP에 세션을 닫아야합니다.
세션 상태를 추적 할 필요가없는 페이지의 경우 자동 생성 세션을 닫으면 일부 리소스를 저장할 수 있습니다. 다음 페이지 지침을 사용하십시오. <%@ page session = "false"%>
20. JDBC 및 I/O
응용 프로그램이 대규모 데이터 세트에 액세스 해야하는 경우 블록 추출을 사용하는 것을 고려해야합니다. 기본적으로 JDBC는 매번 32 행의 데이터를 추출합니다. 예를 들어, 5000 행의 레코드 세트를 가로지 않으려면 JDBC는 모든 데이터를 추출하기 전에 데이터베이스를 157 번 호출해야합니다. 블록 크기가 512로 변경되면 데이터베이스에 대한 호출 수는 10 배로 줄어 듭니다.
21. 서블릿 및 메모리 사용 <br /> 많은 개발자들은 많은 양의 정보를 사용자 세션에 마음대로 저장합니다. 때로는 세션에 저장된 물체는 가비지 수집 메커니즘에 의해 재활용되지 않습니다. 성능의 관점에서 볼 때 일반적인 증상은 사용자가 시스템의 주기적으로 속도가 느려지고 있다고 생각하지만 특정 구성 요소의 이유를 기반으로 할 수는 없다는 것입니다. JVM의 힙 공간을 모니터링하면 비정상적인 메모리 사용 변동으로 나타납니다.
이러한 유형의 메모리 문제를 해결하는 두 가지 주요 방법이 있습니다. 첫 번째 방법은 세션 범위를 가진 모든 콩에서 httpsessionBindingListener 인터페이스를 구현하는 것입니다. 이러한 방식으로 valueUnbound () 메소드가 구현되는 한 Bean에서 사용하는 리소스를 명시 적으로 해제 할 수 있습니다.
또 다른 방법은 가능한 빨리 세션을 무효화하는 것입니다. 대부분의 응용 프로그램 서버에는 세션 무효화 간격을 설정할 수있는 옵션이 있습니다. 또한 세션의 setMaxinactiveinterval () 메소드는 프로그래밍 방식으로 호출 될 수 있습니다.
22. 버퍼 마크를 사용하십시오
일부 응용 프로그램 서버에는 JSP에 대한 버퍼 마킹 기능이 추가되었습니다. 예를 들어 BEA의 Weblogic 서버는 버전 6.0 이후이 기능을 지원하며 Open Symphony 프로젝트는이 기능도 지원합니다. JSP 버퍼링 태그는 두 페이지 조각과 전체 페이지를 버퍼링 할 수 있습니다. JSP 페이지가 실행되면 대상 조각이 이미 버퍼에 있으면 조각을 생성하는 코드를 더 이상 실행할 필요가 없습니다. 페이지 수준 버퍼링은 지정된 URL에 요청을 캡처하고 전체 결과 페이지를 버퍼링합니다. 이 기능은 쇼핑 바구니, 카탈로그 및 포털 홈페이지에 매우 유용합니다. 이러한 응용 프로그램의 경우 페이지 수준 버퍼링은 후속 요청에 대한 페이지 실행 결과를 저장할 수 있습니다.
23. 올바른 인용 메커니즘을 선택하십시오
일반적인 JSP 애플리케이션 시스템에서 헤더 및 바닥 글 부분이 종종 추출 된 다음 필요에 따라 헤더 및 바닥 글을 소개합니다. 현재 JSP 페이지에 외부 리소스를 도입하는 두 가지 주요 방법이 있습니다. 지침 포함 및 작업 포함.
지침 포함 : 예를 들어 < %@ include file = "Copyright.html" %>. 이 지침은 컴파일 시간에 지정된 리소스를 소개합니다. 컴파일하기 전에 포함 지시문 및 지정된 리소스가 포함 된 페이지는 파일로 병합됩니다. 참조 된 외부 리소스는 컴파일 시간에 결정되며 런타임시 리소스를 결정하는 것보다 더 효율적입니다.
acture 포함 : 예를 들어 <jsp : 포함 page = "Copyright.jsp" />. 이 조치는 지정된 페이지가 실행 된 후 생성 된 결과를 소개합니다. 런타임에 완료되므로 출력 결과 제어가 더 유연합니다. 그러나 인용 된 콘텐츠가 자주 변경 될 때 또는 메인 페이지 요청이 나타나기 전에 참조 페이지를 결정할 수없는 경우에 동작을 포함시키는 것은 비용 효율적입니다.
24. 더 이상 필요한 세션이 필요하지 않습니다
더 이상 활성화되지 않은 세션을 지우려면 많은 응용 프로그램 서버에는 기본 세션 타임 아웃 (일반적으로 30 분)이 있습니다. 애플리케이션 서버가 더 많은 세션을 저장 해야하는 경우 메모리 용량이 충분하지 않으면 운영 체제는 메모리 데이터의 일부를 디스크로 전송합니다. 디스크에 저장하고 "메모리 밖"예외를 던질 수도 있습니다. 대규모 시스템에서는 직렬화 세션이 비싸다. 세션이 더 이상 필요하지 않은 경우 httpsession.invalidate () 메소드를 제 시간에 호출하여 세션을 지워야합니다. httpsession.invalidate () 메소드는 일반적으로 응용 프로그램의 종료 페이지에서 호출 될 수 있습니다.
25. 배열을 다음과 같이 선언하지 마십시오 : Public Static Final.
26. 해시 맵의 횡단 효율에 대한 토론
해시 맵에는 키와 값 쌍에 종종 트래버스 작업이 있으며, 두 가지 방법이 있습니다 : Map <String, String []> paramap = new
Hashmap <string, String []> (); ............ // 첫 번째 루프 세트 <string> appfieldDefids = paramap.keyset (string appfieldDefid : AppFieldDefids) {String [ ] 값 = paramap.get (appfieldDefid); ......} // (Entry <string, String []> entry : paramap.entryset ()) {String appfieldDefid = actory.getKey ); string [] value = entry.getValue (); .......} 첫 번째 구현은 두 번째 구현보다 훨씬 덜 효율적입니다.
분석은 다음과 같습니다. set <string> appfieldDefids = paramap.keyset ();
코드는 다음과 같습니다.
public set <k> keyset () {set <k> ks = keyset; return (ks! = null? ks : (keyset = new Keyset ());} 개인 클래스 키 세트 확장 actractSet <k> {public iterator <k > iterator () {return newKeyiterator ();} public int size () {return size;} public boolean contains (object o) {return containsKey (o);} public boolean remak (object o) {return hashmap.this.removeentryforkey (o)! = null;} public void clear () {hashmap.this.clear ();}}실제로, 개인 클래스 키 세트를 반환하는데, 이는 AbstractSet에서 상속되어 세트 인터페이스를 구현합니다.
for/in 루프의 구문을 살펴 보겠습니다.
for (선언 : 표현)
성명
실행 단계에서 다음 공식으로 변환됩니다.
for (iterator <e> #i = (expression) .iterator (); #i.hashnext ();) {
선언 = #i.next ();
성명
}
따라서 hashmap.keyset (). iterator ()는 첫 번째 명령문에서 호출됩니다 (String AppfieldDefid : AppfieldDefids)
이 방법은 NewKeyiterator ()라고합니다.
반복자 <k> newKeyiterator () {
새로운 keyiterator ()를 반환합니다.
}
개인 클래스 Keyiterator 확장 해시 테이터 <k> {
public k next () {
return nextEntry (). getKey ();
}
}
따라서 For에서는 (Entry <String, String []> entry : paramap.entryset ())에 대한 두 번째 루프에 사용 된 반복기를 다음과 같이 호출합니다.
친절한
Private Class Entryiterator 확장 해시 테이터 <map.entry <k, v >> {
public map.entry <k, v> next () {
반환 nextentry ();
}
}
현재 첫 번째 루프는 키를 얻고 두 번째 루프는 해시 맵의 진입 효율을 얻습니다. 두 번째 루프는 루프에 반사되므로 첫 번째 루프는 여전히 필요합니다. Hashmap의 get (Object Key)를 사용하여 값 값을 얻으십시오.
public v get (객체 키) {
객체 k = maskNull (키);
int hash = 해시 (k);
int i = indexfor (Hash, table.length);
입력 <k, v> e = 테이블;
while (true) {
if (e == null)
널 리턴;
if (e.hash == hash && eq (k, e.key))
return e.value;
e = e.next;
}
}
실제로 해시 값을 사용하여 해당 항목을 다시 비교하고 결과를 얻는 것이 해시 맵을 두 번 입력하는 것과 같습니다.
두 번째 루프에서는 입력 값을 얻은 다음 키와 값을 직접 가져옵니다.이 값은 첫 번째 루프보다 더 효율적입니다. 실제로,지도의 개념에 따르면, 두 번째 루프를 사용하는 것이 더 좋습니다.
27. 배열 (배열) 및 Arrylist 사용
배열 ([]) : 가장 효율적이지만 용량은 고정되어 있으며 동적으로 변경할 수 없습니다.
Arraylist : 용량은 역동적으로 성장할 수 있습니다.
효율성 및 유형 확인에 따라 배열은 배열 크기를 결정할 수없는 경우에만 사용해야합니다!
ArrayList는 복잡한 배열 버전입니다
Arraylist는 객체 유형 배열을 캡슐화합니다 배열의 방법.
ArrayList는 객체를 저장하면 유형 정보가 폐기되고 모든 객체가 객체로 차단되지 않지만 런타임에 오류 가보고됩니다.
참고 : JDK5는 제네릭에 대한 지원을 추가했으며 ArrayList를 사용할 때 유형 확인을 수행 할 수 있습니다.
이 관점에서 배열리스트와 어레이의 차이는 주로 동적 용량 증가의 효율로 인한 것입니다.
28. 해시 맵 및 Arraylist를 사용해보십시오 .
29. StringBuffer와 StringBuilder의 차이점 :
java.lang.stringbuffer 스레드-안전한 변이성 문자 시퀀스. 문자열과 같은 문자열 버퍼이지만 수정할 수 없습니다.
StringBuilder. 이 클래스와 비교할 때 Java.lang.stringBuilder 클래스는 일반적으로 동일한 작업을 모두 지원하기 때문에 선호해야하지만 동기화를 수행하지 않기 때문에 더 빠릅니다. 더 나은 성능을 위해서는 Stirngbuffer 또는 Stirngbuilder의 용량을 최대한 지정해야합니다. 물론 작동하는 문자열의 길이가 16자를 초과하지 않으면 필요하지 않습니다. 같은 경우 StripngBuilder를 사용하면 StringBuffer를 사용하는 것과 비교하여 약 10% -15%의 성능 향상을 달성 할 수 있지만 멀티 스레드가 불안한 위험이 필요합니다. 실제 모듈 식 프로그래밍에서 특정 모듈을 담당하는 프로그래머는 모듈이 다중 스레드 환경에 배치 될지 여부를 명확하게 결정하지 못할 수 있습니다. 시스템의 병목 현상이 StringBuffer에 있는지 확인할 수없고 모듈이 멀티 스레드 모드로 실행되지 않도록하십시오. 그렇지 않으면 StringBuffer를 사용하십시오.
기타 보충제 :
1. 더 이상 시간에 사용되지 않고 NULL로 설정된 명확한 개체
2. 최종, 정적 및 기타 키워드를 가능한 한 사용하십시오.
3. 버퍼링 된 물체를 가능한 한 많이 사용하십시오
Java 소스 파일 및 컴파일 된 클래스 파일을 더 작은 CODE를 최적화하는 방법
1 상속을 사용하려고합니다.
2 Java 컴파일러의 최적화 옵션 열기 : Javac -o이 옵션은 클래스 파일에서 줄 번호를 삭제하고 인라인 메소드 호출로 일부 개인, 정적 및 최종 소규모 세그먼트 메소드를 선언합니다.
3 공통 코드를 추출하십시오
4 큰 배열을 초기화하지 않습니다. 배열을 초기화하는 것은 Java 코드의 수량 일뿐입니다. 배열에 저장된 경우 먼저이 데이터를 문자열에 넣은 다음 런타임 동안 문자열을 배열로 구문 분석 할 수 있습니다.
5. 날짜 유형 객체는 많은 날짜 객체를 저장하려면 많은 공간을 차지합니다.
긴 유형, 사용시 날짜 유형으로 변환하십시오
6. 클래스 이름, 메소드 이름 및 변수 이름에 대한 짧은 이름을 사용하여 Hashjava, Obfuscate 및 JshRink를 사용 하여이 작업을 자동으로 완료하십시오.
7 정적 최종 유형의 변수를 인터페이스로 정의합니다.
8 산술 작업이 왼쪽 / 오른쪽 이동에 사용될 수있는 경우, 동일한 작업을 여러 번 사용하지 마십시오.
2. 변수를 두 번 초기화하지 마십시오
Java는 고유 한 클래스 생성자를 호출하여 기본적으로 변수를 기본적으로 알려진 값으로 초기화합니다. 모든 객체는 null로 설정되고 정수 (바이트, 짧은, int, long)는 0으로 설정되고, float 및 double은 0.0으로 설정되고 부울 변수는 False로 설정됩니다. 이는 새로운 키워드를 사용하여 객체를 만들 때 모든 일련의 생성자가 자동으로 호출되는 것처럼 다른 클래스에서 확장되는 클래스에 특히 중요합니다.
3. 가능한 한 수업을 결승하게하십시오
최종적으로 표시된 클래스는 확장 할 수 없습니다. Java.lang.string과 같은 핵심 Java API에는이 기술의 예가 많이 있습니다. 문자열 클래스를 최종으로 표시하면 개발자가 자신이 구현하는 길이의 방법을 만들지 못하게합니다.
더 깊이 말하면, 수업이 최종적이면 수업의 모든 방법은 최종입니다. Java 컴파일러는 모든 방법을 인화 할 수 있습니다 (이것은 컴파일러의 구현에 따라 다름). 테스트에서 평균 성능이 50%증가한 것을 보았습니다.
9. 예외는 버려야 할 곳에 던져집니다.
{some.method1 (); (Method2Exception e) {// 예외 처리 2} try {some.method3 ()} catch (method3exception e) {// 예외 처리 3}. 다운로드 된 코드는 컴파일러가 최적화하기가 더 쉽습니다.
{some.method1 (); method2 (); catch (method3exception e) {// 예외 처리 3}
10. 루프의 최적화
바꾸다…
for (int i = 0; i <collection.size (); i ++) {
...
}
와 함께…
for (int i = 0, n = collection.size (); i <n; i ++) {
...
}
5. Java + Oracle Application System을 개발할 때 오라클 파서의 구문 분석 부담을 줄이기 위해 Java에 대문자 형태 임베디드 SQL 문을 사용해보십시오.
10. 게으른 적재 전략을 채택하십시오. 즉, 필요할 때 생성을 시작하십시오.
예를 들면 : 문자열 str =“aaa”;
if (i == 1) {
list.add (str);
}
다음으로 대체해야합니다.
if (i == 1) {
문자열 str =“aaa”;
list.add (str);
}
12. 루프에서 사용하지 마십시오.
노력하다 {
} 잡다() {
}
가장 바깥 쪽 층에 배치해야합니다
위는이 기사에 관한 것입니다.
시간을내어 기사를 친구들과 공유하거나 의견을 남겨주세요. 귀하의 지원에 진심으로 감사드립니다!