반응형

java 소수점 처리

 - 데이터 타입이 float 이나 double 이어야 합니다.

 

ex) 나누기 연산을 해서 소수 둘째자리까지 출력하는 방법.

1. String.format

 - 반올림 된 값으로 결과값 출력.

 - 소수점 자릿수 지정(고정)

private static void div(int mb) {
        double gb = (double)mb / 1024;
        System.out.println("\n---------------------------------");
        System.out.println("" + mb + " / 1024 = " + gb);

        System.out.println("String.format = " + String.format("%.2f", gb));
}

div(1024);
div(1540);
div(1550);
div(1400);


결과 :
---------------------------------
1024 / 1024 = 1.0
String.format = 1.00

---------------------------------
1540 / 1024 = 1.50390625
String.format = 1.50

---------------------------------
1550 / 1024 = 1.513671875
String.format = 1.51

---------------------------------
1400 / 1024 = 1.3671875
String.format = 1.37

 

2. BigDecimal

 - 반올림/올림/내림 설정 가능.

 - 소수점 자릿수 지정(고정 / 마지막이 0 인 경우 버림 가능)

private static void div(int mb) {
        double gb = (double)mb / 1024;
        System.out.println("\n---------------------------------");
        System.out.println("" + mb + " / 1024 = " + gb);

        BigDecimal bdMb = new BigDecimal(mb);
        BigDecimal bdKb = new BigDecimal(1024);
        System.out.println("BigDecimal = " + bdMb.divide(bdKb, 2, RoundingMode.DOWN));
        System.out.println("BigDecimal(stripTrailingZeros) = " + bdMb.divide(bdKb, 2, RoundingMode.DOWN).stripTrailingZeros());
}
    
div(1024);
div(1540);
div(1550);
div(1400);


---------------------------------
1024 / 1024 = 1.0
BigDecimal = 1.00
BigDecimal(stripTrailingZeros) = 1

---------------------------------
1540 / 1024 = 1.50390625
BigDecimal = 1.50
BigDecimal(stripTrailingZeros) = 1.5

---------------------------------
1550 / 1024 = 1.513671875
BigDecimal = 1.51
BigDecimal(stripTrailingZeros) = 1.51

---------------------------------
1400 / 1024 = 1.3671875
BigDecimal = 1.36
BigDecimal(stripTrailingZeros) = 1.36

 

3. DecimalFormat

 - 반올림 된 값으로 결과값 출력.

 - 소수점 자릿수 지정(고정 / 마지막이 0 인 경우 버림 가능 / 0 버림 갯수 지정 가능)

private static void div(int mb) {
        double gb = (double)mb / 1024;
        System.out.println("\n---------------------------------");
        System.out.println("" + mb + " / 1024 = " + gb);

        DecimalFormat formatter = new DecimalFormat("0.##");
        System.out.println("DecimalFormat(0.##) = " + formatter.format(gb));

        DecimalFormat formatter2 = new DecimalFormat("0.0#");
        System.out.println("DecimalFormat(0.0#) = " + formatter2.format(gb));
}

div(1024);
div(1540);
div(1550);
div(1400);


결과 :
---------------------------------
1024 / 1024 = 1.0
DecimalFormat(0.##) = 1
DecimalFormat(0.0#) = 1.0

---------------------------------
1540 / 1024 = 1.50390625
DecimalFormat(0.##) = 1.5
DecimalFormat(0.0#) = 1.5

---------------------------------
1550 / 1024 = 1.513671875
DecimalFormat(0.##) = 1.51
DecimalFormat(0.0#) = 1.51

---------------------------------
1400 / 1024 = 1.3671875
DecimalFormat(0.##) = 1.37
DecimalFormat(0.0#) = 1.37

 

4. DecimalFormat + BigDecimal

 - 반올림 된 값으로 결과값 출력.

 - 소수점 자릿수 지정(고정 / 마지막이 0 인 경우 버림 가능 / 0 버림 갯수 지정 가능)

private static void div(int mb) {
        double gb = (double)mb / 1024;
        System.out.println("\n---------------------------------");
        System.out.println("" + mb + " / 1024 = " + gb);

        DecimalFormat formatter = new DecimalFormat("0.##");
        DecimalFormat formatter2 = new DecimalFormat("0.0#");
        System.out.println("DecimalFormat(BigDecimal, 0.##) = " + formatter.format(bdMb.divide(bdKb, 2, RoundingMode.DOWN)));
        System.out.println("DecimalFormat(BigDecimal, 0.0#) = " + formatter2.format(bdMb.divide(bdKb, 2, RoundingMode.DOWN)));
}
    
div(1024);
div(1540);
div(1550);
div(1400);
        

결과 :
---------------------------------
1024 / 1024 = 1.0
DecimalFormat(BigDecimal, 0.##) = 1
DecimalFormat(BigDecimal, 0.0#) = 1.0

---------------------------------
1540 / 1024 = 1.50390625
DecimalFormat(BigDecimal, 0.##) = 1.5
DecimalFormat(BigDecimal, 0.0#) = 1.5

---------------------------------
1550 / 1024 = 1.513671875
DecimalFormat(BigDecimal, 0.##) = 1.51
DecimalFormat(BigDecimal, 0.0#) = 1.51

---------------------------------
1400 / 1024 = 1.3671875
DecimalFormat(BigDecimal, 0.##) = 1.36
DecimalFormat(BigDecimal, 0.0#) = 1.36

 

반응형
반응형

엑셀 파일 읽기 시 아래 에러 발생시 해결 방법입니다.

 

라이브러리 추가

apache poi 라이브러리를 추가합니다.

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>5.2.3</version>
		</dependency>

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>5.2.3</version>
		</dependency>

 

엑셀 파일 읽기 소스 코드

public static void readExcel() {
		try {
            FileInputStream file = new FileInputStream("file_path.xlsx");
            IOUtils.setByteArrayMaxOverride(Integer.MAX_VALUE);

            //Create Workbook instance holding reference to .xlsx file
            XSSFWorkbook workbook = new XSSFWorkbook(file);

            //Get first/desired sheet from the workbook
            XSSFSheet sheet = workbook.getSheetAt(0);

            //Iterate through each rows one by one
            Iterator<Row> rowIterator = sheet.iterator();
            while (rowIterator.hasNext()) {
                Row row = rowIterator.next();
                //For each row, iterate through all the columns
                Iterator<Cell> cellIterator = row.cellIterator();

                while (cellIterator.hasNext()) {
                    Cell cell = cellIterator.next();
                    //Check the cell type and format accordingly
                    switch (cell.getCellType()) {
                        case NUMERIC:
                            System.out.print(cell.getNumericCellValue() + "\t");
                            break;

                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;

                        case BLANK :
                        	System.out.print("\t");
                            break;

                        default:
                            throw new IllegalStateException("Unexpected value: " + cell.getCellType());
                    }
                }
                System.out.println("");
            }
            file.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
	}

 

에러 발생

 

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.logging.log4j.Logger.atDebug()Lorg/apache/logging/log4j/LogBuilder;

 

 

 

해결 방법

		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-to-slf4j -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-to-slf4j</artifactId>
			<version>2.17.2</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.17.2</version>
		</dependency>

 

반응형

'프로그래밍 > Java' 카테고리의 다른 글

java 소수점 처리  (1) 2023.10.10
Java Stream 설명  (0) 2023.05.26
Stream reduce 간단 설명  (0) 2023.05.20
java file.encoding  (0) 2022.07.12
[JAVA] java.lang.UnsatisfiedLinkError: no net in java.library.path  (1) 2021.06.25
반응형

Java Stream

 

Java Stream 특징

- Java 8부터 도입된 기능으로, 컬렉션, 배열, 파일 등의 데이터 요소를 처리하는 연산을 지원하는 함수형 Stream 입니다.

- 데이터 소스로부터 연속된 데이터 흐름을 제공하여 데이터를 처리합니다.

- 데이터를 효율적으로 처리할 수 있으며, 병렬 처리를 포함한 다양한 연산을 적용할 수 있습니다. 

- 데이터를 필터링, 매핑, 정렬, 그룹핑 등 다양한 작업을 수행할 수 있으며, 함수형 프로그래밍 스타일을 지원하여 코드를 간결하고 가독성 있게 작성할 수 있습니다.

- 중간 연산과 최종 연산으로 구성된 파이프라인을 만들 수 있습니다. 중간 연산은 다른 Stream 을 반환하며, 최종 연산은 최종 결과를 반환합니다.

 

Java Stream 처리 단계

1. 데이터 소스 생성

 - 컬렉션, 배열, 파일 등의 데이터 소스로부터 Stream 을 생성합니다.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();

 

2. 중간 연산

 - 필터링, 매핑, 정렬 등의 작업을 수행할 수 있습니다.

stream = stream.filter(n -> n % 2 == 0) // 짝수만 필터링
               .map(n -> n * 2)         // 각 요소를 2배로 매핑
               .sorted();               // 정렬

 

3. 최종 연산

 - 리스트, 배열, 요소 개수 등 다양한 결과를 얻을 수 있습니다.

// 요소 개수 세기(count)
long count = numbers.stream()
                   .count();
System.out.println(count);  // 출력: 5

// 요소들의 합 구하기(sum)
int sum = numbers.stream()
                .mapToInt(Integer::intValue)
                .sum();
System.out.println(sum);  // 출력: 15


// 최대값 찾기(max)
Optional<Integer> max = numbers.stream()
                               .max(Comparator.naturalOrder());
System.out.println(max.orElse(0));  // 출력: 5


// 요소들의 평균 구하기(average)
OptionalDouble average = numbers.stream()
                               .mapToInt(Integer::intValue)
                               .average();
System.out.println(average.orElse(0));  // 출력: 3.0


// 요소들을 리스트로 변환(collect)
List<Integer> doubledNumbers = numbers.stream()
                                      .map(n -> n * 2)
                                      .collect(Collectors.toList());
System.out.println(doubledNumbers);  // 출력: [2, 4, 6, 8, 10]

※ 이외에도 최소값 찾기(min), 문자열로 연결하기(join), 그룹화하기(groupingBy) 등 다양한 최종 연산이 있습니다.

 

Java Stream VS Parallel Stream

구분 Stream Parallel Stream
데이터 처리 방식 순차적으로 연산을 수행 병렬로 연산을 수행
처리 속도 단일 CPU 코어에서 동작하며, 작업을 직렬로 처리.  멀티코어 시스템에서 데이터 처리 속도를 높일 수 있음.
작업을 분할하고 스레드 간의 동기화 오버헤드가 발생할 수 있으므로, 작업량이 많거나 데이터가 충분히 큰 경우에 이점.
스레드 안전성 - 멀티 스레드에서 작업을 수행하므로 스레드 안전성에 주의.
thread-safe 한 자료구조를 사용하거나 동기화 메커니즘을 적절하게 사용
순서 보장 연산 순서가 보장되며, 요소 순서 유지 병렬로 처리하기 때문에 요소의 순서가 보장되지 않을 수 있음. 
사용처 데이터의 순서가 중요하거나 상호작용이 필요한 경우 유용 멀티코어 CPU 시스템에서 병렬 처리에 특히 유용하며, 대량의 데이터를 동시에 처리해야 할 때 성능 향상을 제공

 

소스로 비교

public static void main(String[] args) {
    // 데이터 소스
    int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // stream
    int sumSequential = Arrays.stream(numbers).sum();
    System.out.println("Sum (Sequential): " + sumSequential);

    // parallel stream
    int sumParallel = Arrays.stream(numbers)
        .parallel()
        .sum();
    System.out.println("Sum (Parallel): " + sumParallel);
}
    
// 결과 출력
Sum (Sequential): 55
Sum (Parallel): 55

stream : Arrays.stream(numbers)를 호출하여 스트림을 생성하고, sum() 메서드를 호출하여 모든 요소의 합을 계산

parallel stream : Arrays.stream(numbers)를 호출하여 스트림을 생성한 후 .parallel() 메서드를 호출하여 병렬 스트림으로 전환, 그리고 나서 sum() 메서드를 호출하여 병렬로 모든 요소의 합을 계산

※  합계를 구하는 간단한 작업. 작은 데이터셋이므로 parallel stream 을 사용하여도 순차 stream 과 동일한 결과.

 

parallel stream 잘못된 사용 예제

public static void main(String[] args) {
    // 데이터 소스
    int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 잘못된 사용 예제
    int sum = Arrays.stream(numbers)
        .parallel()
        .map(n -> {
            if (n == 5) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return n;
        })
        .sum();
        
    System.out.println("Sum: " + sum);
}

// 결과 출력
Sum: 50

 - 배열 numbers를 데이터 소스로 사용하여 parallel stream을 이용하여 요소들을 처리하고 합계(sum)를 계산

- parallel stream 내부의 map 연산에서 특정 조건(n == 5)에 따라 5인 경우 1초의 지연을 발생

- parallel stream은 요소를 병렬로 처리하기 때문에 map 연산의 각 요소는 병렬로 실행

- 조건 n == 5를 만족하는 요소가 존재할 경우 1초의 지연이 발생하고, 이로 인해 전체 연산에 대한 지연이 발생

 

parallel stream 처리 순서 확인

-public static void main(String[] args) {
    // 데이터 소스
    int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    Arrays.stream(numbers)
        .parallel()
        .map(n -> {
            System.out.println("Map: " + n + " - " + Thread.currentThread().getName());
            return n;
        })
        .forEach(n -> System.out.println("ForEach: " + n + " - " + Thread.currentThread().getName()));
-}

// 결과 출력
Map: 1 - main
Map: 2 - ForkJoinPool.commonPool-worker-1
Map: 5 - ForkJoinPool.commonPool-worker-2
Map: 4 - ForkJoinPool.commonPool-worker-3
Map: 3 - ForkJoinPool.commonPool-worker-4
Map: 6 - main
ForEach: 6 - main
ForEach: 1 - main
ForEach: 2 - ForkJoinPool.commonPool-worker-1
ForEach: 3 - ForkJoinPool.commonPool-worker-4
ForEach: 4 - ForkJoinPool.commonPool-worker-3
ForEach: 5 - ForkJoinPool.commonPool-worker-2

- 배열 numbers를 데이터 소스로 사용하여 parallel stream을 생성하고, map 연산과 forEach 연산을 순차적으로 수행.

- map 연산은 각 요소를 변환하고, forEach 연산은 각 요소를 출력.

- Thread.currentThread().getName() : 현재 실행 중인 스레드의 이름 출력.

- map 연산은 여러 스레드에서 동시에 실행되므로 요소의 처리 순서가 보장되지 않음. 

- forEach 연산은 마지막에 순차적으로 수행되며, 최종 결과인 출력도 순차적으로 출력

※ 중간 연산과 최종 연산의 특성에 따라 다를 수 있으므로, 순서에 의존하는 작업을 수행하는 경우에는 주의가 필요

 

Java 8 에 추가된 기능인 Stream 에 대해서 간략하게 알아보았습니다. 더불어 parallel stream 과의 비교도 확인하였습니다.

반응형
반응형

Java Stream reduce 함수에 대한 설명입니다.

 

바로 소스로 들어가보자!

import java.util.OptionalInt;
import java.util.stream.IntStream;

public class StreamReduce {

    public static void main(String[] args) {
        //Optional<T> reduce(BinaryOperator<T> accumulator);
        OptionalInt reduced1 = IntStream.range(1, 5) // [1, 2, 3, 4]
                        .reduce((a, b) -> {
                            System.out.println("a = " + a);
                            System.out.println("b = " + b);
                            return Integer.sum(a, b);
                        });

        System.out.println(reduced1.getAsInt());


        //T reduce(T identity, BinaryOperator<T> accumulator);
        int reduced2 = IntStream.range(1, 5) // [1, 2, 3, 4]
                        .reduce(10, (a, b) -> {
                            System.out.println("a = " + a);
                            System.out.println("b = " + b);
                            return Integer.sum(a, b);
                        });

        System.out.println(reduced2);
    }
}

 

긴말 필요 없이 결과도 바로 확인해보자!

a = 1
b = 2
a = 3
b = 3
a = 6
b = 4
10

a = 10
b = 1
a = 11
b = 2
a = 13
b = 3
a = 16
b = 4
20

 

Stream 생성 했던 IntStream 의 range 함수는 Javadoc 으로 확인해본다.

IntStream (Java Platform SE 8 ) (oracle.com)

 

IntStream (Java Platform SE 8 )

Returns an infinite sequential ordered IntStream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc. The first element (position 0) in the IntStream will be the prov

docs.oracle.com

 

※ 첫번째 파라미터는 포함, 두번째 파라미터는 불포함

 - 항상 헷갈리는 부분이니까 꼼꼼히 읽어보자!!

static IntStream range(int startInclusive, int endExclusive)
Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1.
API Note:
An equivalent sequence of increasing values can be produced sequentially using a for loop as follows:

     for (int i = startInclusive; i < endExclusive ; i++) { ... }
 
Parameters:
startInclusive - the (inclusive) initial value
endExclusive - the exclusive upper bound
Returns:
a sequential IntStream for the range of int elements

 

 

자, 이제 본격적으로 Stream reduce 에 대한 설명 들어보고 가실께여~

1. 먼저 파라미터가 1개인 reduce 함수

        //Optional<T> reduce(BinaryOperator<T> accumulator);
        OptionalInt reduced1 = IntStream.range(1, 5) // [1, 2, 3, 4]
                        .reduce((a, b) -> {
                            System.out.println("a = " + a);
                            System.out.println("b = " + b);
                            return Integer.sum(a, b);
                        });

        System.out.println(reduced1.getAsInt());

첫번째 실행

 - a : Stream 의 첫번째 값 = 1

 - b : Stream 의 두번째 값 = 2

 - a + b = 3 을 반환(return) 한다.

두번째 실행

 - a : 첫번째 실행한 결과 값 = 3

 - b : Stream 의 다음(세번째) 값 = 3

 - a + b = 6 을 반환(return) 한다.

세번째 실행

 - a : 두번째 실행한 결과 값 = 6

 - b : Stream 의 다음(네번째) 값 = 4

 - a + b = 10 을 반환(return) 한다.

최종 실행 결과 값으로 10을 반환한다.

 

2. 먼저 파라미터가 2개인 reduce 함수

 - reduce 함수의 첫번째 파라미터는 초기 값을 의미한다.

        //T reduce(T identity, BinaryOperator<T> accumulator);
        int reduced2 = IntStream.range(1, 5) // [1, 2, 3, 4]
                        .reduce(10, (a, b) -> {
                            System.out.println("a = " + a);
                            System.out.println("b = " + b);
                            return Integer.sum(a, b);
                        });

        System.out.println(reduced2);

 

첫번째 실행

 - a : 초기 값 = 10

 - b : Stream 의 첫번째 값 = 1

 - a + b = 11 을 반환(return) 한다.

두번째 실행

 - a : 첫번째 실행한 결과 값 = 11

 - b : Stream 의 다음(두번째) 값 = 2

 - a + b = 13 을 반환(return) 한다.

세번째 실행

 - a : 두번째 실행한 결과 값 = 13

 - b : Stream 의 다음(세번째) 값 = 3

 - a + b = 16 을 반환(return) 한다.

네번째 실행

 - a : 세번째 실행한 결과 값 = 16

 - b : Stream 의 다음(네번째) 값 = 4

 - a + b = 20 을 반환(return) 한다.

최종 실행 결과 값으로 20을 반환한다.

 

 

위에서 살펴본 Stream reduce 두 함수의 차이는 초기 값이 있냐 없냐의 차이이다.

그리고 Stream reduce 함수에서 가장 중요하게 봐야할 부분은 accumulator 의 동작 방식이다.

첫번째, 두번째 인자에 값이 어떻게 전달되어 최종 결과값을 반환하는지에 대한 이해만 있다면 어렵지 않을 것이다.

 

Stream reduce 에 대한 Javadoc 페이지도 같이 확인하면 좋을 것 같아 링크를 건다.

Stream (Java Platform SE 8 ) (oracle.com)

 

Stream (Java Platform SE 8 )

A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())

docs.oracle.com

 

반응형
반응형

java encoding 순서

System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("Charset.defaultCharset=" + Charset.defaultCharset());
System.out.println("InputStreamReader.getEncoding=" + new InputStreamReader(new FileInputStream("./PrintCharSets.java")).getEncoding());

 

1. jvm 옵션(OS 환경변수보다 최우선시 적용)

 - java -Dfile.encoding=euckr

2. env LC_ALL

- LC_ALL 이 설정되어 있으면 LC_CTYPE 값도 LC_ALL 값으로 덮어써진다.

3. env LC_CTYPE

- LC_ALL 이 설정 안되어 있으면 개별로 설정된 LC_CTYPE 적용.

4. env LANG

- LC_ALL 과 LC_CTYPE 이 설정되어 있지 않다면 LC_ALL 을 제외한 나머지 LC_* 값은 LANG 값으로 덮어써진다.

- 따라서, LC_CTYPE 은 LANG 값과 같아진다.

 

결국 linux 에서는 jvm 옵션을 설정하지 않으면 locale 명령어의 결과 중 LC_CTYPE 값이 적용된다고 보면 된다.

 

반응형

'프로그래밍 > Java' 카테고리의 다른 글

Java Stream 설명  (0) 2023.05.26
Stream reduce 간단 설명  (0) 2023.05.20
[JAVA] java.lang.UnsatisfiedLinkError: no net in java.library.path  (1) 2021.06.25
Too many open files  (2) 2021.06.14
환경변수 값 읽어오기.  (0) 2021.04.05
반응형

현상 : 잘 돌아가고 있는 Java 프로세스에서 갑자기 에러 발생.

원인 : Java 프로세스가 떠 있는 상태에서 JDK 버전을 업데이트 해서 에러 발생.

해결 : Java 프로세스 재구동.

 

[WARN ] Failed to create a new channel from an accepted socket. {nioEventLoopGroup-3-1}
at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:155)
java.lang.UnsatisfiedLinkError: no net in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at sun.net.ExtendedOptionsImpl.lambda$static$0(ExtendedOptionsImpl.java:48)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.ExtendedOptionsImpl.<clinit>(ExtendedOptionsImpl.java:47)
    at sun.nio.ch.SocketChannelImpl$DefaultOptionsHolder.defaultOptions(SocketChannelImpl.java:242)
    at sun.nio.ch.SocketChannelImpl$DefaultOptionsHolder.<clinit>(SocketChannelImpl.java:229)
    at sun.nio.ch.SocketChannelImpl.supportedOptions(SocketChannelImpl.java:251)
    at sun.nio.ch.SocketChannelImpl.setOption(SocketChannelImpl.java:169)
    at sun.nio.ch.SocketAdaptor.setBooleanOption(SocketAdaptor.java:271)
    at sun.nio.ch.SocketAdaptor.setTcpNoDelay(SocketAdaptor.java:306)
    at io.netty.channel.socket.DefaultSocketChannelConfig.setTcpNoDelay(DefaultSocketChannelConfig.java:253)
    at io.netty.channel.socket.DefaultSocketChannelConfig.<init>(DefaultSocketChannelConfig.java:53)
    at io.netty.channel.socket.nio.NioSocketChannel$NioSocketChannelConfig.<init>(NioSocketChannel.java:470)
    at io.netty.channel.socket.nio.NioSocketChannel$NioSocketChannelConfig.<init>(NioSocketChannel.java:467)
    at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:106)
    at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:151)
    at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:75)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)
[WARN ] Failed to create a new channel from an accepted socket. {nioEventLoopGroup-3-1}
at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:155)
java.lang.NoClassDefFoundError: Could not initialize class sun.nio.ch.SocketChannelImpl$DefaultOptionsHolder
    at sun.nio.ch.SocketChannelImpl.supportedOptions(SocketChannelImpl.java:251)
    at sun.nio.ch.SocketChannelImpl.setOption(SocketChannelImpl.java:169)
    at sun.nio.ch.SocketAdaptor.setBooleanOption(SocketAdaptor.java:271)
    at sun.nio.ch.SocketAdaptor.setTcpNoDelay(SocketAdaptor.java:306)
    at io.netty.channel.socket.DefaultSocketChannelConfig.setTcpNoDelay(DefaultSocketChannelConfig.java:253)
    at io.netty.channel.socket.DefaultSocketChannelConfig.<init>(DefaultSocketChannelConfig.java:53)
    at io.netty.channel.socket.nio.NioSocketChannel$NioSocketChannelConfig.<init>(NioSocketChannel.java:470)
    at io.netty.channel.socket.nio.NioSocketChannel$NioSocketChannelConfig.<init>(NioSocketChannel.java:467)
    at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:106)
    at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:151)
    at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:75)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

 

[/proc/16105/fd ] ls -al | grep java
15 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/lib/charsets.jar (deleted)
25 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/lib/jsse.jar (deleted)
4 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/lib/rt.jar (deleted)
7 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/lib/ext/cldrdata.jar (deleted)
8 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/lib/ext/localedata.jar (deleted)

 

 

반응형

'프로그래밍 > Java' 카테고리의 다른 글

Stream reduce 간단 설명  (0) 2023.05.20
java file.encoding  (0) 2022.07.12
Too many open files  (2) 2021.06.14
환경변수 값 읽어오기.  (0) 2021.04.05
[Spring Boot] log4jdbc 설정.  (1) 2020.01.16
반응형

Too many open files

java.io.IOException: Too many open files
Operation timed outerverSocketChannelImpl.accept0(Native Method)
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
    at io.netty.util.internal.SocketUtils$5.run(SocketUtils.java:119)
    at io.netty.util.internal.SocketUtils$5.run(SocketUtils.java:116)
    at java.security.AccessController.doPrivileged(Native Method)
    at io.netty.util.internal.SocketUtils.accept(SocketUtils.java:116)
    at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:147)
    at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:75)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)


FD(File Descriptor/open files) 수가 부족한 경우 발생.

FD 사용 개수 확인.
$ lsof -p [PID] | wc -l
$ lsof -u [UID] | wc -l


Network connetion 개수 확인
$ netstat -an | wc -l

 

FD(File Descriptor/open files)
 - 프로세스가 가질 수 있는 소켓 포함 파일 개수
 - Java에서 소켓 통신(HTTP API, JDBC 커넥션 등)은 open file 옵션을 따라간다.


User Limit 확인
$ ulimit -aS


Hard Limit 확인
$ ulimit -aH


JDK 내부 코드상에서 Hard Limit 값이 soft limit에 update.
 - Java 프로세스는 Hard Limit 까지 file open 가능.


https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html
$ java -XX:+PrintFlagsFinal -version | grep MaxFDLimit
     bool MaxFDLimit                                = true                                {product}
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)

MaxFDLimit 옵션이 true일 경우 setrlimit 으로 limit을 증가.


Limit 설정.
$ vi /etc/security/limits.conf
계정명 soft nofile 40960
계정명 hard nofile 40960

보통 soft limit과 hard limit을 같은 값으로 설정한다.





Java에서 동시에 생성 가능한 쓰레드 수는 max user processes를 따라간다.

ps 명령어로 스레드 생성 개수를 확인(-L 옵션 : Show threads, possibly with LWP and NLWP columns.)
$ ps -efL | grep java | grep -v grep | wc -l
UID PID PPID LWP C NLWP STIME TTY TIME CMD

- PPID : 부모 프로세스 ID
- LWP : LWP(Light Weight Process, is thread). 쓰레드 ID
- C : CPU 사용율
- NLWP : LWP(Number Light Weight Process). 해당 프로세스에서 동작하고 있는 쓰레드 개수.
- STIME : 프로세스 시작 시간
- TIME : 총 CPU 사용 시간

반응형

'프로그래밍 > Java' 카테고리의 다른 글

java file.encoding  (0) 2022.07.12
[JAVA] java.lang.UnsatisfiedLinkError: no net in java.library.path  (1) 2021.06.25
환경변수 값 읽어오기.  (0) 2021.04.05
[Spring Boot] log4jdbc 설정.  (1) 2020.01.16
Rabbit MQ 간단 사용.  (0) 2018.12.21
반응형

OS / JVM 환경변구 값 읽어오기.

public static void main( String[] args ) {
                System.out.println("OS 환경변수 값");
                System.getenv().entrySet().forEach(e -> {
                        System.out.println("\t" + e.getKey() + "=" + e.getValue());
                });
                // export java_test_value="TEST VAL"
                System.out.println("OS 환경변수 java_test_value 값 = " + System.getenv("java_test_value"));


                System.out.println("");
                System.out.println("JVM 환경변수 값");
                Properties props = System.getProperties();
                for(Enumeration en = props.propertyNames(); en.hasMoreElements();) {
                        String key = (String)en.nextElement();
                        String value = props.getProperty(key);
                        System.out.println("\t" + key + "=" + value);
                }
                System.out.println("JVM 환경변수 user.name값 = " + System.getProperty("user.name"));
                System.out.println("JVM 환경변수 user.test값 = " + System.getProperty("user.test", "user.test property is null."));
}

 

반응형

'프로그래밍 > Java' 카테고리의 다른 글

[JAVA] java.lang.UnsatisfiedLinkError: no net in java.library.path  (1) 2021.06.25
Too many open files  (2) 2021.06.14
[Spring Boot] log4jdbc 설정.  (1) 2020.01.16
Rabbit MQ 간단 사용.  (0) 2018.12.21
singleton 객체.  (0) 2018.12.06
반응형

spring boot 에서 Log4jdbc 를 사용해 실행된 쿼리 로그 확인.

1. log4jdbc를 dependency에 추가

<!-- log4jdbc -->
<dependency>
    <groupId>org.bgee.log4jdbc-log4j2</groupId>
    <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
    <version>1.16</version>
</dependency>


2. datasource 설정.
 - spring.datasource.driverClassName 은 모든 DBMS 공통.
 - spring.datasource.url 은 jdbc-db name 사이에 log4jdbc 추가.
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/test


3. log4j2 설정 파일 생성.
- 파일 path
resources/log4jdbc.log4j2.properties

 - 파일 내용.
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0
(sql문 최대 출력 라인 수. 0:무제한, 미설정 : 한줄)


4. Logger 추가.

<logger name="jdbc" level="OFF"/>

<!-- SQL문만 로깅, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문 출력 -->
<logger name="jdbc.sqlonly" level="OFF"/>

<!-- SQL문과 수행 시간 정보(milliseconds) 포함 -->
<logger name="jdbc.sqltiming" level="DEBUG"/>

<!-- ResultSet을 제외한 모든 JDBC 호출 정보 로깅. JDBC 문제를 추적해야 할 필요가 있는 경우에만 사용 -->
<logger name="jdbc.audit" level="OFF"/>

<!-- ResultSet을 포함한 모든 JDBC 호출 정보 로깅. 로그양이 많음 -->
<logger name="jdbc.resultset" level="OFF"/>

<!-- SQL 결과를 table 형태로 로깅 -->
<logger name="jdbc.resultsettable" level="DEBUG"/>

<!-- Connection의 연결과 종료에 관련된 로깅. 메모리 누수 확인? -->
<logger name="jdbc.connection" level="OFF"/>

 

※ Altibase  DB 에 적용 시.
VM옵션 추가 
   -Dlog4jdbc.drivers=Altibase.jdbc.driver.AltibaseDriver

 

반응형

'프로그래밍 > Java' 카테고리의 다른 글

Too many open files  (2) 2021.06.14
환경변수 값 읽어오기.  (0) 2021.04.05
Rabbit MQ 간단 사용.  (0) 2018.12.21
singleton 객체.  (0) 2018.12.06
openfire(xmpp) client  (0) 2018.11.06
반응형



// "guest"/"guest" by default, limited to localhost connections

ConnectionFactory factory = new ConnectionFactory();


factory.setHost("localhost");

factory.setPort(5672);

factory.setVirtualHost("/");

factory.setUsername("name");

factory.setPassword("pw");


//factory.setUri("amqp://name:pw@localhost:5672");


Connection conn = factory.newConnection();

Channel channel = conn.createChannel();


// autoDelete(true) : exchange 를 사용하는 곳이 없으면 삭제. durable 속성과는 상관없음.

// durable : 브로커 재시작 후에도 큐의 상태를 유지 여부.

//channel.exchangeDeclare("aiif.test", "direct", false/*durable*/, false/*autoDelete*/, null);




// exclusive

// connection close 되면 큐 삭제 됨.

// durable, autoDelete 속성과는 상관없음.

//channel.queueDeclare("ExclusiveQueue", false/*durable*/, true/*exclusive*/, false/*autoDelete*/, null);


// auto delete

// queue 에 consuming 하는 client 가 없으면 삭제.

// 일단 queue 를 생성 후 consuming 하는 client 가 있다가 없어진 경우에 삭제됨.

channel.queueDeclare("AutoDeleteQueue", false, false, false, null);


//channel.queueBind("AutoDeleteQueue", "aiif.test", "AutoDeleteQueue");


//DefaultConsumer consumer = new DefaultConsumer(channel);

final boolean autoAck = true;

String tag = channel.basicConsume("AutoDeleteQueue", autoAck/*auto ack*/, new DefaultConsumer(channel) {


        @Override

        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                String message;

                if (body == null) {

                        message = "";

                        System.out.println("body null");

                } else {

                        message = new String(body);

                        System.out.println("message : " + message);

                }

                Map<String, Object> h = properties.getHeaders();

                System.out.println(h);


                String routingKey = envelope.getRoutingKey();

                String contentType = properties.getContentType();

                long deliveryTag = envelope.getDeliveryTag();

                System.out.println("routingKey : " + routingKey);

                System.out.println("contentType : " + contentType);

                System.out.println("deliveryTag : " + deliveryTag);



                MQMessage mqMessage = MQMessageMaker.make(message);

                System.out.println(mqMessage.toString());


                MQMessageBodyHB mqMessageBodyHB = (MQMessageBodyHB)mqMessage.getBody();

                System.out.println(mqMessageBodyHB.getLoad_level());

                System.out.println(mqMessageBodyHB.getAiif_id());


                if(!autoAck) {

                        channel.basicAck(deliveryTag, false/*multiple*/);

                }

        }

});


System.out.println("subscribe queue : AutoDeleteQueue");

//Thread.sleep(10000);


channel.basicCancel(tag);

System.out.println("unsubscribe queue : AutoDeleteQueue");

Thread.sleep(10000);


channel.queueDelete("AutoDeleteQueue");

System.out.println("delete queue : AutoDeleteQueue");

Thread.sleep(10000);


channel.close();

System.out.println("channel close");

Thread.sleep(10000);


conn.close();

System.out.println("connection close");



반응형

'프로그래밍 > Java' 카테고리의 다른 글

환경변수 값 읽어오기.  (0) 2021.04.05
[Spring Boot] log4jdbc 설정.  (1) 2020.01.16
singleton 객체.  (0) 2018.12.06
openfire(xmpp) client  (0) 2018.11.06
openfire 플러그인 개발.  (0) 2018.11.06

+ Recent posts