반응형
반응형
반응형

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

 

반응형
반응형

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
반응형



MyObject destObject = new MyObject();
Class<? extends Object> piClass = destObject.getClass();
Method[] arrayPiMethod = piClass.getDeclaredMethods();

// ================= setter 실행.
for(Method methodPi : arrayPiMethod) {
    String methodName = methodPi.getName();

    try {
        if(methodName.startsWith("set")) {
            Class[] paramObj = methodPi.getParameterTypes();
            Object callParameter = null;
            If(paramObj[0] == String.class) {
                callParameter = new String("test");
            } else If(paramObj[0] == int.class) {
                callParameter = new Integer(1);
            }

            methodPi.invoke(destObject, new Object[] { callParameter } );
        }
    } catch (IllegalArgumentException e) {
    } catch (IllegalAccessException e) {
    } catch (InvocationTargetException e) {
    }
}


// ================= getter 실행.
for(Method methodPi : arrayPiMethod){
    if(methodPi.getName().startsWith("get")) {
        try {
            Object obj = methodPi.invoke(object, new Object[]{});
            System.out.println("return value : " + obj);
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
    }
}



반응형

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

[android] c2dm 보낼때 exception 발생.  (0) 2012.02.20
[이클립스] jad clipse 플러그인.  (0) 2011.10.26
[spring] static 변수에 autowired 설정하기.  (0) 2011.09.20
String -> Json  (0) 2011.09.19
http request post data 읽기.  (0) 2011.09.19
반응형
반응형

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

[Spring3] applicationContext.xml 설정 시 에러.  (0) 2011.07.25
[안드로이드] 개발 환경 구축  (0) 2011.06.24
[spring] 엑셀 다운로드  (0) 2011.03.21
url encoding  (0) 2011.02.18
[link] sitemesh  (0) 2011.01.17
반응형

최범균이 운영하는 자바 및 웹 관련 컨텐츠 제공 블로그


개발자, DBA가 함께 만들어가는 오라클클럽 지식창고!
반응형

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

[spring] 엑셀 다운로드  (0) 2011.03.21
url encoding  (0) 2011.02.18
[이클립스] 플러그인 FindBugs  (0) 2010.06.10
[jsp]DisplayTag 에서 row num 구하기.  (2) 2010.02.23
외부 명령어 실행  (1) 2010.01.29

+ Recent posts