코드스테이츠 - 자바 심화(파일 입출력, 스레드, JVM)

kwak woojong·2022년 5월 20일
0

코드스테이츠

목록 보기
16/36
post-thumbnail

1. 파일 입출력

InputStream, OutputStream

입출력을 위한 Stream임

단방향이라 각각 필요하다.

file의 경우 FileInputStream / FileOutputStream

프로레스의 경우 PipedInputStream / PipedOutputStream

File만 보자

FileOutputStream fileOutput = new FileOutputStream("codeStates.txt");
String word = "test";

byte[] b = word.getBytes(StandardCharsets.UTF_8);
fileOutput.write(b);
fileOutput.close();

OutputStream을 만들었다.

인스턴스를 생성하고 인자에 파일명을 넣어준다.

그리고 byte[]로 변환하여 String을 넣어줌 변환시에 인자는 뭐... 별 필요 없을거 같은데 걍 UTF_8을 넣었다.
그리고 wirte(b)로 내부에 글씨 작성하고 close()

FileInputStream fileInput = new FileInputStream("codeStates.txt");
int i = 0;
while ((i = fileInput.read()) != -1) {
	System.out.print((char) i);
}
fileInput.close();

OutputStream을 만들고 나서 InputStream으로 읽어보자

예제에 while문이 저렇게 되어 있었다. 이게 뭔가 싶었음
아마 fileInput.read()를 사용하면 int값을 뱉는 것으로 보임. indexOf처럼 없을 경우 -1을 뱉지 않을까?
그리고 1글자씩 읽는 것으로 보인다. 그러니까 while을 썼겠지

하여튼 결과값은

FileReader, FileWriter

InputStream, OutputStream은 1byte씩 읽는다.

근데 자바의 문자열은 2byte씩임 (char 기본 단위)

이게 뭔가 안맞잖아? 그래서 문자 전용 클래스가 있다. 그게 저거임.
영어라 InputStream으로 읽었을 때, 안깨졌지 한글로 하면 깨져서 보이게 된다.(위에 예제 코드)

상기 Input, OutputStream 코드 아래에 작성을 더 했다.

FileWriter fileWriter = new FileWriter("codeStates.txt");
fileWriter.append("깨랑까랑");
fileWriter.close();

Writer를 이용해 codeStates.txt에 "깨랑까랑"을 append해봤다. 나는 이게 작동하면 test 뒤에 붙을 줄 알았더니 아에 덮어 씌우더라?

FileReader fileReader = new FileReader("codeStates.txt");
int data = 0;
while (((data=fileReader.read()) != -1)) {
	System.out.print((char) data);
}
fileReader.close();

얘도 read()를 할 때 숫자로 한글자씩 튀어나오나봄 여튼 다음에 없으면 -1을 뱉는 구조인가봐

하여튼 data를 char로 출력하면 된다.

그럼 OutputStream에서 만든 test라는 글자가 사라지고 "깨랑까랑"이 남는다.

File

파일을 다루기 위해 있는 녀석이다. 코드로 보자

File file = new File("codeStates.txt");
String parent = file.getParent();
String path = file.getPath();
String canonicalPath = file.getCanonicalPath();
String absolutePath = file.getAbsolutePath();
boolean b1 = file.canWrite();

System.out.println();
System.out.println("parent = " + parent);
System.out.println("path = " + path);
System.out.println("canonicalPath = " + canonicalPath);
System.out.println("absolutePath = " + absolutePath);
System.out.println("b1 = " + b1);

codeStates.txt 파일을 읽어와서 부모디렉토리,
path(상대경로로 보임),
CanonicalPath는 절대경로인데 ./ ../ 같은 문자를 정리해주는 것으로 보임.
AbsolutePath도 절대경로 인데 ./ ../ 같은 문자는 정리를 안해준다.
canWrite는 지금 얘가 write가 가능한지 뱉는듯


2. 스레드 (Thread)

이걸 초보 개발자들한테 설명한다고? 6개월 안에 뭔갈 만들어야 하는 사람들에게? 후...

스레드는 컴퓨터에 관심 많으신 분들은 다 알 내용이긴 하다.

작업 동시처리라고 생각하면 좀 편함 게임덕후들은 싱글코어만 쓰는 게임을 수 없이 욕했을 테니 멀티 스레딩의 중요성을 알고 있을거다.

멀티스레드는 병렬, 동시 작업을 하고 있다는 의미임. 이거 없으면 게임 못굴린다.

ㄹㅇ 프로그래밍의 중요성인데, cpu가 뭐 8코어에 16스레드면 뭐하냐 프로그래밍상 싱글 스레드를 쓰면 말짱 황임

솔직히 이 스레드만 써도 글을 몇개 써야 할지 모르겠는데, 이걸 정리한다? 에바참치다.

실은 스프링이 알아서 스레드 정리 해주니까 우리는 이런게 있다고 알고만 있자

참고자료 링크

스레드풀 내용은 알고 있으면 참 좋은데, 이거 DB다룰때 커넥션풀 이라는 놈과 느낌이 비슷하다.


3. 자바 가상 머신 (JVM)

JVM을 왜 씀?

초창기 윈도우를 기억한다면 윈도우 전용 프로그램이 좔좔 있던 것을 알 수 있다.

지금의 안드로이드 어플이랑 애플 어플 따로 개발하는 걸 보면 이게 뭔 소린지 알 수 있음.

근데 Java는 운영체제마다 호환성이 중요함 개발할 때도 중요하고?

그래서 나온 개념이 이 JVM이다. 상기 이미지처럼 운영체제에서 여러가지 데이터를 받아 JVM이 중간에 낀 상태에서 프로그램을 구동한다.

그래서 우리가 코드 작성하고 컴파일하고 빌드 될 때 시간이 걸리고 새로운 파일이 만들어지는거임

스택과 힙, 메모리 쪼끔

스택과 힙메모리가 우리 코드 처리할 때 꽤 중요함 상기 이미지가 진짜 보기 좋고 슬라이드 방식이라 이해하기 좋다.

클릭하면 볼 수 있으니 확인 ㄱ


tcp스쿨에서 긁어왔는데

자바가 실행될 때 JVM 메모리는 저런식으로 형성 된다.

메소드 영역은 낮은 주소에 저장되고
힙은 대게 낮은 주소에서 높은 주소로 할당 된다.
스택은 높은 주소에서 낮은 주소로 할당 된다.

이 부분은 안읽어도 됩니다.
주소가 뭐냐면 님 참조값 그냥 System.out.println(member);을 부르면 앞에 뜨는 그게 일종의 주소역할을 한다.

엥 아닌데요?

하여간 64bit 컴퓨터의 주소값은

0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF
이렇게 가진다. 왼쪽이 낮은 주소고 오른쪽이 높은 주소라고 볼 수 있겠다.

32비트는 0을 좀 지우면 주소값임. ㅊC나 C++에선 포인터라고 변수를 가리키는 애도 있는데, 자바는 없다.

저 위에 member가 가리키는게 참조값이고 그거 보고 얘가 찾아감. 즉 자바는 포인터가 없고 참조값을 사용한다.

삼천포로 많이 빠진거 같은데...

하여튼 스택에 우리가 실행한 메소드나 뭔가가 계속 쌓인다. 그게 일정 범위 이상을 넘어가면 자바가 계산하길 포기하고 그게 바로 Stack Overflow가 발생한다.

즉 스택 영역의 주소가 높은 주소에서 낮은 주소로 쭉쭉 쌓여 가다가 힙 영역의 주소랑 만나면?

스택 영역이 주소 범위를 벗어났으니까 Stack Overflow Exception을 뱉는다.

재귀 짤때 엄청 봄 조심하셈

힙과 스택이 서로 엮이는 것 까지 할라면 디게 오래걸리는데, 걍 다들 블로그 찾아보길 바란다.

하여튼 스택은 높은 주소에 점점 쌓이고 이게 해결이 되면 낮은 주소에서 하나하나 빠진다. (왕창빠진다)

이 때 스택은 값을 대부분 가지고 있고, 값을 못가지는 객체 같은 애들은 힙에 연결되어 있음 (참조값)

스택 위에거가 처리되면서 연결된 애들이 빠진다.

근데 힙에서 생성된 애들은 안없어지고 남는데, 얘들을 정리하는게 또 따로 있다.

Garbage Collection

스택에 들어온 애들은 할 일 끝나면 쭉쭉 빠짐

근데 힙에 있는 애들은 그대로 유지가 된다. 그러다가 스택이랑 연결이 끊어지면, 그냥 메모리만 차지하는 쓰레기가 된다.

얘들을 청소해주는게 Garbage Collection임

갈비쥐들을 모아서 없애는 처리 방식이 아니다!

갈비쥐들이 아닌것을 추린 다음에 나머지를 버리는거임 (역집합 ㄱ!)

이 갈비쥐 컬렉션이 발동되면 모든 쓰레드 작업이 중단된다.

이것도 다른 블로그가 정리를 잘해놔씀 링크

young 에는 보통 새로 생겨난 객체들이 많이 있다. eden에 생성됨. 가끔 Minor GC가 작동함. eden이 꽉 차면 사용하는 애들을 survivor 영역으로 밀면서 안쓰는 애들을 지워준다.

old 영역은 young에서 살아남은 애들이 시간이 지나면 저기로 간다. 여긴 Major GC가 발동하고 Mark and Sweep방식을 사용
쓰는 애들을 Mark하고 나머지를 Sweep를 해준다. 만약 쓰는 애가 적다면 순식간에 다 지우게 되겠지?


profile
https://crazyleader.notion.site/Crazykwak-36c7ffc9d32e4e83b325da26ed8d1728?pvs=4<-- 포트폴리오

0개의 댓글