728x90
728x90

Selenium을 맛봤으니 이제는 실습을 해야 할 차례이다.

Selenium은 다양한 웹 브라우저를 조작할 수 있는 라이브러리이다. 이 때, Selenium이 웹 브라우저를 조작하기 위해서는 각 브라우저마다 해당 브라우저를 제어할 수 있는 드라이버가 필요한데, Chrome 웹 브라우저를 조작하기 위해서는 ChromeDriver가 필요하다. 따라서, Selenium을 사용하기 위해서는 ChromeDriver를 다운로드하여 설치해야 한다.

셀레니움은 다양한 언어로 사용할 수 있는데, 자바, 파이썬 등에서 가장 많이 사용된다.

험난했던 chrome web browser 버전 맞추기

이전에 (한참 전…) 에 selenium을 찍먹했을 때는 https://chromedriver.chromium.org/downloads 이곳에서 크롬 웹브라우저를 설치할 수 있었다. 내가 다시 접한 자료들에서도 이곳에서 다운받으라고 하기에 내 크롬 버전이 뭔지도 모르고 가장 최신이라는 94.0.4606.41 을 설치했는데…

계속되는 오류에 지쳐가던 중 내가 사용하는 크롬 버전이 115버전이라는 걸 알게되었다.

https://googlechromelabs.github.io/chrome-for-testing/

크롬드라이버 115.0.5790.170은 여기서 다운받을 수 있다. STATUS가 X로 되어있는 경우도 있는데 이러면 안된다는거다 ;; 기다려야지 뭐

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

chromedriver_path = "/Users/inseoulmate/Downloads/chromedriver-mac-arm64/chromedriver"
service = Service(chromedriver_path)
driver = webdriver.Chrome(service=service)

driver.get("<https://www.genie.co.kr/chart/top200>")

wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, "list-wrap")))

chart_items = driver.find_elements(By.CSS_SELECTOR, ".list-wrap > tbody > tr.list")

for item in chart_items:
    rank = item.find_element(By.CLASS_NAME, "number").text
    title = item.find_element(By.CSS_SELECTOR, ".info .title").text
    artist = item.find_element(By.CSS_SELECTOR, ".info .artist").text

    print(f"{rank}. {title} - {artist}")

# 셀레니움 웹 드라이버 종료
driver.quit()

먼저 코드 전문이다

1. 필요한 것 불러와주기

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Selenium 라이브러리 자체를 임포트해준다.

webdriver : 웹 드라이버를 제어학디 위한 모듈이다. 웹 드라이버는 브라우저를 제어하고 웹 페이지에 엑세스하는데 사용된다.

Service : 웹 드라이버를 실행시키는 데 필요한 서비스를 관리하는 클래스이다. 특정 드라이버를 실행하기 위해 사용된다.

By: 웹 요소를 찾는 방법을 지정하기 위한 클래스이다. By.CLASS_NAME, By.CSS_SELECTOR, 등과 같은 방법을 사용하여 웹 요소를 식별한다.

WebdriverWait : 웹 드라이버를 통해 웹 페이지가 특정 조건을 만족할 때까지 기다리기 위한 클래스이다. 웹 요소의 출현이나 속성 등을 기다리는 데 사용된다 .

expected_conditions : 웹 요소가 특정 조건을 만족하는지 확인하기 위한 클래스이다

EC.presence_of_element_located , EC.visibility_of_element_located 등과 같은 조건을 사용했다.

2. 크롬 드라이버 설정해주기

chromedriver_path = "/Users/inseoulmate/Downloads/chromedriver-mac-arm64/chromedriver"
service = Service(chromedriver_path)
driver = webdriver.Chrome(service=service)

크롬드라이버가 어디 있는지도 찾아야 한다. 이거 찾느라 꽤나 오래 걸렸다. 보통 다운로드에 있다.

절대경로를 복사해서 붙여넣어주면 된다 .

3. 링크 연결하기

driver.get("<https://www.genie.co.kr/chart/top200>")

다음 나는 지니뮤직의 1위부터 100위까지를 스크래핑할거기에 차트 링크를 넣어주었다.

4. 정보 스크래핑하고 변수에 저장하고 출력하기

wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, "list-wrap")))
chart_items = driver.find_elements(By.CSS_SELECTOR, ".list-wrap > tbody > tr.list")

for item in chart_items:
    rank = item.find_element(By.CLASS_NAME, "number").text
    title = item.find_element(By.CSS_SELECTOR, ".info .title").text
    artist = item.find_element(By.CSS_SELECTOR, ".info .artist").text

드라이버 객체를 최대 10초까지 기다리며, 해당 시간 내에 “list-wrap” 클래스가 웹페이지에 나타날 떄까지 기다린다. 이 요소는 음악 차트 목록을 감싸는 부모 요소이다 .

BY.CSS_SELECTOR를 사용해 CSS선택자를 이용하여 해당 요소들을 찾고 반복문을 실행해주었다. 이후 item.find_element를 사용하여 요소 내에서 순위, 제목 및 아티스트 정보를 해당 요소들에서 찾아낸다. 이 정보들은 ‘rank’ , ‘title’, ‘artist’ 변수에 저장된다.

나머지는 print 함수를 이용해 출력하는것과 , 드라이버를 종료하는 것으로 마무리된다.

 

이렇게 잘 출력되었다. 개인적으로 뉴진스-ETA 노래 너무 좋다. 안 들어본 사람 있으면 꼭 들어봤으면 좋겠다.

300x250
728x90
728x90
  1. 기본 지식
    •  HTML/CSS 기초
    •  Python 기본 문법
    •  웹의 동작 원리 (HTTP, HTTPS)
  2. 라이브러리 및 도구 익히기
    •  Selenium: 웹 브라우저 자동화 도구 (동적 페이지 크롤링에 유용)
    •  requests: 웹 페이지의 HTML 코드를 가져오기 위한 라이브러리
    •  BeautifulSoup4: HTML 및 XML 문서를 파싱하기 위한 라이브러리
  3. 기본 크롤링 및 스크래핑 실습
    •  정적 웹페이지에서 데이터 추출하기
    •  동적 웹페이지(예: AJAX, 웹소켓 사용) 크롤링하기
  4. 로봇 배제 표준 및 이슈 이해
    •  크롤링 시 주의할 법적, 윤리적 이슈 알아보기
    •  robots.txt 파일 해석하기
  5. 고급 크롤링 및 스크래핑 기법
    •  스크롤 다운 페이지 크롤링
    •  로그인 필요한 페이지 크롤링
    •  Scrapy: 대규모 웹 크롤링 프레임워크 익히기
    •  웹사이트의 anti-crawling 기법 대응 전략
  6. 데이터 처리 및 저장
    •  데이터 정규화 및 클린징
    •  데이터 저장: CSV, JSON, 데이터베이스 등
  7. 프로젝트 및 실습
    •  실제 웹사이트에서 데이터를 크롤링하고, 필요한 정보를 추출하여 저장하는 프로젝트 진행
    •  가능하다면, 크롤링한 데이터를 활용한 간단한 데이터 분석이나 시각화 실습도 좋습니다.
  8. 지속적 학습 및 최신 트렌드 파악
    •  웹 크롤링 관련 커뮤니티, 블로그, 포럼 등을 통해 최신 기술과 트렌드를 지속적으로 파악
    •  법적, 윤리적 이슈에 대한 최신 정보도 계속 업데이트 해야 함
    OSINT를 공부하려면 웹 크롤링과 스크래핑을 공부해야 하기에 로드맵을 만들어 보았다.
 
300x250
728x90
728x90

⌨️ 셀레니움이란?

웹 애플리케이션을 위한 테스팅 프레임워크로 시작되었지만, 웹 페이지를 자동화하거나 웹 크롤링을 위해 널리 사용되고 있따. 이를 사용하면, JS로 구성된 동적 웹 페이지를 크롤링 가능하다

🚀 1. 설치

pip install selenium 

🚀 2. 웹 드라이버 설치

셀레니움은 브라우저를 제어하기 위한 웹 드라이버가 필요하다.

예를 들어 chrome을 사용할 경우 chromeDriver를 설치해야 한다.

🚀 3. 기본 사용법

from selenium import webdriver

# 웹드라이버 초기화 (이 경우는 Chrome을 사용)
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')

# 웹 페이지 접근
driver.get('https://www.example.com')

# 웹 요소 찾기 및 조작
element = driver.find_element_by_id('element_id')
element.send_keys('some text')
element.click()

# 페이지의 내용 가져오기
page_source = driver.page_source

# 브라우저 종료
driver.quit()

🚀 4. 기다리기 (Implicit. & Explicit Waits)

동적 웹페이지는 요소가 로드되는 데 시간이 걸릴 수 있으므로 원하는 웹 요소가 충분히 로드될 떄까지 기다려야 한다 .

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Explicit Wait 예제
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'element_id'))
)

🚀  5. 동작(Actions)

복잡한 사용자 상호작용, 예를 들면 드래그 앤 드롭, 마우스 오버 등을 시뮬레이트 할 수 있다.


Selenium의 크롤링 속도는 ‘requests’나 ‘BeautifulSoup’ 와 같은 도구보다 느릴 수 있다. 따라서 필요한 경우에만 사용하는 것이 좋다. 이를 사용하면 매우 강력하고 유연한 웹 크롤링 및 자동화가 가능하지만, 동시에 많은 지원을 사용할 수 있으므로 효율적인 크롤링 전략을 구상하는 것이 중요하다 .

🤷🏻‍♂️Selenium, 왜 써야 하는가?

🌐 동적 웹 페이지 크롤링

많은 웹사이트들이 AJAX나 JAVASCRIPT를 사용하여 동적으로 데이터를 로드한다.

‘requests’로 페이지를 가져올 떄, 초기 Html만 가져올 수 있으며, JAVASCIRPT로 생성된 동적 콘텐츠는 포함되지 않을 수 있따. ‘selenium’은 실제 브라우저를 제어하므로 JAAVASCRIPT를 실행하여 페이지의 완전한 내용을 가져올 수 있다

🌐 사용자 상호작용 시뮬레이션

어떤 웹 페이지는 특정 버튼을 클릭하거나, 폼을 채우고 제출하거나, 스크롤 다운하는 등의 사용자 상호작용을 필요로 할 떄가 있따. ‘Selenium’은 이러한 상호작용을 자동화하고 시뮬레이션 할 수 있다.

🌐 웹 페이지의 상태 변경 감지

로그인 상태, 쿠키, 세션 등의 웹 페이지 상태를 유지하고 변경하려면 이를 사용하는 것이 더 쉬울 수 있다.

🌐 페이지 Redirections

몇몇 웹사이트는 자동 리다이렉션을 사용할 수 있으며, Selenium은 이러한 리다이렉션을 자연스럽게 처리할 수 있다.

🌐 CAPTCHA 및 보안

일부 웹사이트는 자동화된 엑세스를 차단하기 위해 captcha나 다른 보안 조치를 사용할 수 있다. 이런 경우, 자동화된 도구로 captcha를 우회하는 것은 권장되지 않지만, ‘selenium’을 사용하여 수동으로 capcha를 입력하거나 다른 보안 조치를 처리할 수 있다 .

🌐 브라우저 특정 작업

셀레니움은 여러 브라우저에서 테스트를 수행하거나. 브라우저의 특정 기능 (예: 확장 프로그램 사용, 개발자 도구 사용 등)을 활용하는 작업에 유용합니다.

💡 그렇다고 해서 모든 웹 크롤링 작업에 셀레니움을 사용해야 하는 것은 아니다. 가능하다면 먼저 Requests와 BeautifulSoup 을 사용하여 필요한 데이터를 가져오는 것이 좋다. 셀레니움은 추가적인 지원을 사용하고, 크롤링 속도가 느릴 수 있기 때문에 필요한 경우에만 사용하는 것이 효율적이다 .
 
300x250
728x90
728x90
  1. 키워드 검색 :
    • 가장 기본적인 웹 검색 기술
    • 검색하고자 하는 내용과 관련된 핵심 단어를 사용한다
  2. 인용부호 (””) :
    - “” 안에 특정 문구를 입력하면 해당 문구가 포함된 결과를 찾을 수 있다 .
  3. 이러면 유튜브 후기만 뜬다
  4. 논리 연산자 사용 :
    • 논리 연산자 AND, OR, NOT을 사용하여 검색 결과를 조정할 수 있다
      • AND : 두 단어를 함께 포함하는 결과 검색
      • OR: 두 단어 중 하나를 포함하는 결과를 검색한다
      • NOT: 특정 단어를 제외한 결과를 검색한다

4


. 사이트 내 검색 :
- 특정 웹 사이트 내에서만 검색하고 싶은 경우, “site:사이트주소” 형식으로 검색어를 입력한다

300x250
728x90
728x90

🤷🏻‍♂️ OSINT란?

공공에서 접근이 가능한 오픈소스를 이용하여 원시 데이터를 수집하는 것을 말한다. 이는 다양한 소스를 활용하여 정보를 수집하며, 이러한 소스들은 인터넷에서 공개된 데이터, 뉴스, 소셜 미디어 , 블로그, 포럼, 공공 기록, 공개 문서 등이 포함될 수 있다. 이 정보들은 보통 무료로 접근 가능하다.

osint라는 용어는 해당 분야에 익숙하지 않은 사람들에게 엄청난 해커 같은 이미지를 준다. 정보 수집은 해커의 영역이긴 하지만 … 이를 적절하게 활용하면 비즈니스에 큰 이점이 될 수 있다.,

OSINT는 다양한 목적으로 활용될 수 있다. 일반적으로 정보수집, 검증,리서치. 경쟁 정보 수집 , 보안 취약점 식별, 비즈니스 분석, 범죄 수사 등에서 사용되며, 간편하고 빠른 접근성을 제공한다. 다양한 데이터 소스를 활용하여 비굦덕 포괄적인 정보를 얻을 수 있다는 장점도 있다.

🤔 OSINT로 뭘 찾는가 ?

  1. 인터넷 검색 : 구글 , 브라우저, 인스타그램 등 소셜 미디어 검 등을 활요하여 정보를 찾는다
  2. 소셜 미디어 모니터링: 트위터 , 페이스북, 인스타그램 등 소셜 미디어 플랫폼을 모니터링하여 공개 정보를 수집한다.
  3. 웹 크롤링과 스크래핑 : 웹 페이지를 자동으로 탐색하여 데이터를 추출한다
  4. 오픈 데이터 포털 : 정부 기관이나 공공기관에서 제공하는 오픈 데이터를 활용한다
  5. 뉴스 기사 및 블로그 : 다양한 뉴스 사이트와 블로그에서 정보를 수집한다
  6. 포럼과 커뮤니티 : 특정 주제에 대한 정보를 얻기 위해 관련 포럼이나 커뮤니티를 참조한다

중요한 점은 OSINT는 항상 합법적인 수단으로 사용되어야 하고, 개인 정보 침해와 같은 불법적인 활동으로 사용해서는 안된다.

😲 왜 필요한가?

시간이 지남에 따라 인터넷은 넓은 세상에서 사람들과 쉽게 교류할 수 있게 만들었다. 전 세계 사람들이 정보를 교환하고 소통할 수 있게 되었고, 세계는 이제 ‘정보화 시대’가 되었다. 정보화 시대에 활용 할 수 있는 자료가 엄청나게 많음에도 불구하고 활용하지 못한다는 것은 정말 아쉬운 일이 아닌가?

정부 부처, 비정부 조직 및 기업 또한 이를 사용해 비공개 기밀 정보들을 수집한다. 이는 저작권 또는 개인 정보 보호법을 위반하지 않고 대중이 합법적으로 액세스할 수 있어야 하기에 다른 형태의 인텔리전스와 구별된다. 이러한 구분으로 인해 단순한 보안 서비스 이상에 적용 가능한 OSINT 소스를 수집할 수 있다.

⌨️ OSINT 도구에는 어떤 것이 있을까?

OSINT 프레임워크 - 거의 모든 종류의 소스 또는 플랫폼을 위한 데이터 검색 및 수집 도구이다

Babel X - 이 국제 검색 시스템은 AI를 사용하기 때문에 언어 장벽을 넘어설 수 있다. 클라우드 기반 서비스이다 .

Google Dorks - 고급 인수가 포함된 똑똑한 구글 검색 쿼리를 사용하는 수집 방법

Shodan - 검색 엔진의 한 종류이며 그 약점에 대해 알수 있는 방법

maltego- 그래픽 상관 분석을 위해 정보를 수집하고 모든 정보를 통합하는 OSINT 도구

🚀 OSINT를 보안에 어떻게 사용하는가 ?

  1. 취약점 식별 : 조직의 인프라, 시스템, 웹 애플리케이션 등의 취약점을 식별할 수 있다. 공개된 정보를 조사하여보안 취약점을 파악하고, 이를 해결한다
    • 정보를 수집해 취약한 시스템, 애플리케이션, 서비스 등과 관련된 정보를 찾아낸다
    • 보안 뉴스 사이트와 블로그를 확인하여 최신 보안 취약점에 대한 정보를 파악한다. 취약점 공개와 관련된 정보를 찾을 수 있다
    • 해킹 커뮤니티나 보안 관련 포럼을 모니터링하여 취약점에 관한 힌트를 찾아낸다
  💡 딥러닝에도 사용된다. 
  다층신경망을 통해 복잡한 패턴과 특징을 학습하여 문제를 해결하는 기술인 
  딥러닝에서 자료를 모아 갖다주는 데 OSINT가 활용된다.

👩🏻‍💼 그럼 OSINT는 검색 잘 되는 검색 엔진일 뿐인거야?

→ OSINT는 검색 엔진이 아니다. 정보를 수집하는 방법 또는 접근하는 접근 방법을 일컫는 말이다.

공개된 소스를 활요하여 정보를 수집하는 것을 의미한다고 몇 번을 언급했는데, osint는 단순히 검색 엔진으로 접근할 수 있는 정보만을 말하는 것이 아니라, 인터넷 상의 다양한 소스들을 포함하는 정보 수집 방법 전체를 포괄하는 개념이다 .

검색 엔진은 OSINT를 수행하는 데에 도움이 될 수 있는 도구 중 하나이다.

💡 하지만  OSINT는 단순히 검색 엔진에 의존하지 않고 
다양한 데이터 소스를 활용하여 정보를 수집하고 분석하는 전체적인 접근 방법을 의미한다 .
300x250
728x90
728x90

하고 싶은 걸 하겠다고 다짐한 이후 내가 그렇게 재밌어했던 darkweb에 대해서 공부해보기로 했다.
정보보안 관련 분야이다. 앞으로 포렌식과 OSINT를 공부해 보려 하는데, 감이 안 잡혀 gpt에게 로드맵 좀 짜달라고 했다. 앞으로 하루하루 정해진 분량을 공부해나가면서 포스팅을 진행해보려고 한다.

🚀 지피티가 추천한 DARK WEB과 OSINT를 공부하기 위해 걸쳐야 할 로드맵![]

  1. 기본 웹 검색 기술 습득하기:
    • 기초적인 웹 검색 기술과 검색엔진의 사용법을 익힌다
    • Google, Bing, DuckDuckGo 등의 검색 엔진을 활용하여 정보를 찾아본다
  2. OSINT 기초 개념 이해:
    • OSINT의 개념과 목적을 이해한다
    • OSINT에서 사용되는 주요 용어와 도구에 대해 익숙해진다
  3. 웹 크롤링과 스크래핑:
    • Python과 BeautifulSoup, Scrapy 등의 라이브러리를 활용하여 웹 크롤링과 스크래핑을 연습한다
    • DEEP WEB에서 데이터를 수집하는 방법에 대해 학습한다
  4. 소셜 미디어 모니터링:
    • 소셜 미디어 플랫폼의 API를 이용하여 공개된 데이터를 수집하는 방법을 익힌다
    • DEEP WEB에서 소셜 미디어 데이터를 수집하고 분석하는 방법을 연습한다
  5. DEEP WEB 데이터베이스 및 포럼 검색:
    • DEEP WEB에서 특정 데이터베이스와 포럼을 찾고 데이터를 수집하는 기법을 학습한다
    • 검색 엔진의 키워드 사용과 고급 검색 기능에 익숙해진다
  6. 보안 및 개인 정보 보호 이해:
    • OSINT를 수행하는 과정에서 법적, 윤리적인 측면과 개인 정보 보호에 대한 이해한다
  7. OSINT 도구 사용:
    • Maltego, Shodan, SpiderFoot 등의 OSINT 도구를 사용하여 DEEP WEB에서 정보를 수집하고 분석하는 방법을 학습한다
  8. 실전 프로젝트:
    • 자신의 관심 주제와 목표에 맞는 OSINT 프로젝트를 수행한다 DEEP WEB에 관련된 특정 정보를 탐색하거나 특정 주제에 대한 리서치를 진행하는 등의 프로젝트를 진행해본다
  9. 계속해서 업데이트:
    • 보안과 웹 기술은 계속해서 변화하고 발전하기 때문에 지속적인 학습과 업데이트가 필요하다. 관련 도서, 온라인 강의, 웹 사이트, 블로그 등을 활용하여 최신 정보를 습득하고 스킬을 향상시켜야 한다
    • 하나하나 공부하면서 업로드해보자 !
300x250
728x90
728x90

🚀 오늘의 꼬꼬무

20230727 목요일

오늘의 꼬꼬무 주제 : 변수


나는 항상 ‘꼬리에 꼬리를 무는’ 이라는 말을 굉장히 좋아한다.

앞으로 1일 1 포스팅, 꼬꼬무 프로젝트를 해볼 예정이다.

꼬리에 꼬리를 무는 질문들로 공부해보며, 공부한 것들을 포스팅해 보자는 취지의 프로젝트이다.


💁🏻 변수란 무엇인가?

우리가 10+20을 하면 10과 20, 그리고 + 를 기억하여 그 결과를 계산한다.

→ 이는 컴퓨터도 마찬가지이다.

→ 10은 리터럴 + 는 연산자이다. 이들을 모두 알아서 해석한다.

그럼 10과 20은 어디에 저장하는가? 이들은 모두 메모리에 저장된다.

각 메모리에는 메모리 주소가 있다

→ 이 숫자들은 모두 이진으로 저장된다.

메모리 주소에 저장된 이 친구들을 불러내야 하는데, 직접 메모리 주소를 사용하면 위험도가 있다.

→ 메모리 주소에 직접 접근하다가 시스템의 메모리에 잘못 접근하면 엄청난 문제가 생길 수 있기 때문이다.

⇒ 그래서 자바스크립트는 메모리 주소에 직접적으로 접근하지 못한다.

🤔 그렇다면 우리는 한 개의 값으로 연산을 할 때마다 그 값을 새로 입력해줘야 하는 것인가?

😃 그래서 변수라는 개념이 나온 것이다 !

내가 만약 10이라는 값을 할당 한다고 하자

💡 할당이란 값을 변수에 넣는 것이다

이때 10은 고유한 메모리에 들어갈 것이다

이때 각 메모리 주소를 전부 입력할 수 없으니 (접근이 제한되어 있으니) 우리는 메모리 주소에 이름을 붙인다. 이를 변수라고 한다.


🤔그렇다면 질문이 있는데…

🤷🏻‍♂️변수와 물리적 주소 가상 주소까지… 공부의 시작이였던 이 질문

👩🏻‍💼: A라는 변수에 10이라는 값을 할당하는 프로그램을 작성하고 프로그램을 실행 후 완전히 종료하고 다시 실행했다. 그렇다면 10이라 값은 다시 한 번 다른 메모리 자리에 할당되고 이 변수의 이름이 A가 되는 것인가?

그렇다면 이전에 할당된 메모리는 쓰지 않을 텐데, 어떻게 관리하는 것인가?

⏹  : 프로그램을 실행하면 컴퓨터는 해당 프로그램을 메모리에 로드하고 실행하는데, 이 과정에서 변수와 데이터는 메모리에 할당된다.

변수 A에 10이라는 값을 할당하는 경우, 10이라는 데이터가 메모리에 저장되고 해당 메모리 위치에 변수 이름인 A가 매핑된다.

프로그램을 실행하고 완전히 종료한 후 다시 실행하면, 기본적으로 운영체제는 새로운 프로세스로 실행을 시작한다. 이전 실행에서 사용된 메모리는 더이상 사용하지 않는다.

🤷🏻‍♂️이 메모리는 어떻게 처리하냐라고 묻는다면…?

운영체제는 프로세스의 실행과 종료를 관리하고 각 프로세스가 필요로 하는 메모리를 할당하고 회수하는 작업이 수행된다.

프로그램이 종료되면 해당 프로세스에 사용된 메모리는 운영체제에 의해 회수되어 재사용 가능한 상태가 된다. 이렇게 함으로써 메모리 사용을 좀 더 효율적으로 관리하고 충돌이나 메모리 누수와 같은 문제를 방지한다.

메모리 누수란?

💡 메모리 누수란? : 응용 프로그램에서 데이터를 메모리에 저장했다가, 필요없어졌을때 적절하게 제거되지 않는 것. ‘메모리 릭 (Memory leak)이라고도 한다

  • 메모리에 데이터가 남아 있어도 운영 체제가 의도한 것이라면 데이터 누수가 아니다
  • windows vista 이후의 운영체제 및 안드로이드에선 옛날만큼 메모리 공간이 빡빡하지 않다는 것을 감안하여 종료시킨 프로그램을 일부러 메모리 상에 남겨두기도 한다

→ 사용자가 다시 실행시켰을때 더 빠르게 응답할 수 있다.

→ 사용자가 다른 작업을 하다가 다시 메모리가 부족해지면 알아서 정리해준다.

??? 엥? 저번에 들었던 가비지 컬렉션의 개념이 생각나. 그 개념은 언어 자체가 메모리를 관리하는 거였는데??

운영 체제의 메모리를 관리 VS 가비지 컬렉션

🌐 운영 체제가 메모리를 관리하는 것

  • 운영 체제는 프로세스가 메모리를 요청하면 해당 메모리를 할당하고 , 프로세스가 종료되면 메모리를 회수하여 재사용 가능한 상태로 만든다
  • 프로세스들 간의 메모리 공간을 분리하여 충돌이나 오류를 방지하고, 시스템의 안정성을 유지한다

🗑 가비지 컬렉션

  • 프로그래밍 언어의 런타임 환경에서 담당하는 기능으로, 메모리를 동적으로 관리하는 상황에서 발생하는 메모리 누수를 방지하고 자동으로 더 이상 사용되지 않는 메모리를 회수하는 역할을 함
  • 더이상 필요없는 변수, 객체들을 식별하고 메모리를 자동으로 회수하여 재사용 가능한 상태로 만들어준다.
  • JAVA, C#, PYTHON 등의 언어에서 가비지 컬렉션을 지원하며 언어의 런타임 환경이 가비지 컬렉션을 담당한다
운영 체제는 컴퓨터 자원을 관리함
프로세스들의 실행과 메모리 할당/ 회수 담당

가비지 컬렉션은 런타임에서 메모리 관리를 담당
사용하지 않는 것을 식별하고 자동으로 회수

사실 아직도 그 둘의 차이를 잘 이해를 못 했었다.

그래서 예시를 들어서 공부해보기로 했다

💡 이렇게 가정해보자

  1. VS CODE를 실행한다
  2. A = 10이라는 값을 할당하는 코드를 쓴다
  3. 코드를 실행한다
  4. 종료한다
  5. VS CODE를 닫는다
  • VS CODE를 실행한다

→ 운영 체제는 VScode 프로세스에 필요한 메모리를 할당하고, 사용할 수 있도록 확보한다.

😺 : 이때 좀 더 자세한 과정을 보자면…

→ 가상 주소와 물리 주소에 대한 설명은 이 과정을 모두 적고 공부해보았다.

1. 프로세스 생성

  • VSCODE를 실행하면 운영 체제는 새로운 프로세스를 생성한다.
  • 프로세스는 실행 중인 프로그램을 나타내며, 자신만의 독립된 메모리 공간을 가지고 실행한다

2. 가상 주소 공간 할당

  • 운영 체제는 VS CODE 프로세스에게 가상 주소 공간을 할당한다. 가상 주소 공간은 각 프로세스가 독립적으로 사용하는 가상의 메모리 공간을 의미한다.
  • 이 가상 주소 공간은 실제 물리적 메모리와는 분리되어 있으며, 프로세스가 사용하는 주소들은 가상 주소로 매핑되어 실제 메모리에 할당된다.

3. 물리적 메모리 할당

  • 가상 주소 공간에 할당된 메모리는 실제 물리적 메모리에 매핑되어야 한다.
  • 이때 운영 체제는 VSCODE 프로세스가 필요로 하는 물리적 메모리를 확보한다.
  • 즉 , 운영 체제는 VSCODE에 필요한 메모리 공간을 실제 물리적 메모리에 할당하여 사용할 수 있도록 한다.

4. 메모리 보호

  • 운영 체제는 각 프로세스들간의 메모리 공간을 보호하기 위해 메모리 보호 기법을 사용한다.
  • 각 프로세스는 자신의 주소 공간에서만 접근이 가능하고, 다른 프로세스의 주소 공간에는 접근할 수 없도록 제한된다.

5. 프로세스 실행

  • VSCODE 프로세스가 메모리를 할당받고 초기화되면, 운영 체제는 해당 프로세스를 실행시킨다.
  • 이제 VSCODE는 자신의 가상 주소 공간 내에서 실행되며, 필요한 데이터와 코드가 메모리에 로드되어 사용된다

7. 변수 쓰기 (가비지 컬렉션)

  • 자바스크립트의 경우
// main.js
let A = 10;
console.log(A);

변수 A에 10이 할당되고, 콘솔에 10이 출력된다. 코드 실행이 완료되면 NODE.JS가 사용한 메모리는 운영 체제에 의 해 회수된다.

JS는 가비지 컬렉션을 내장해 이때 가비지 컬렉터에 의해 식별되고 자동으로 회수된다.

  • C언어의 경우
#include <stdio.h>

int main() {
    int A = 10;
    printf("%d\n", A);
    return 0;
}

코드 실행이 완료되면 C프로그램이 사용한 메모리는 운영 체제에 의해 회수된다. C 언어는 메모리 할당과 해제를 개발자가 직접 관리해야 하므로, 메모리 누수가 발생하지 않도록 메모리 해제 코드를 작성해야 한다

8. 프로세스 종료:

  • VSCODE 실행이 끝나고 VSCODE를 종료하면, 운영 체제는 해당 프로세스가 사용한 메모리를 회수한다.
  • 프로세스가 종료되면 할당된 가상 주소 공간과 물리적 메모리는 다른 프로세스가 사용할 수 있도록 해제된다.
  • 이렇게 함으로써 VSCODE의 실행에 사용된 메모리가 운영 체제에 의해 회수되고 재사용 가능한 상태가 된다

💁🏻  가상 주소 란 무엇인가?

가상 메모리란? 프로세스는 가상 주소를 사용하고, 데이터를 사용할때 물리 주소로 변환해준다는 것이다.

가상 주소 : 프로세스가 참조하는 주소

물리 주소 : 실제 메모리 주

MMU : CPU에 코드 실행시, 가상 주소 메모리 접근이 필요할때, 해당 주소를 물리 주소 값으로 변환시켜주는 하드웨어 장치.

🤓 그럼 가상 주소 왜 쓰는데?

  1. 프로세스 독립성 : 각 프로세스는 각각의 가상 주소 공간을가지고 있다. 이로 인해 프로세스는 서로의 주소 공간에 영향을 미치지 않고 독립적으로 실행될 수 있다.

→ 따라서 하나의 프로세스에서 발생한 오류나 메모리 접근 오류가 다른 포르세스에 영향을 미치지 않아 안정성이 향상된다

🤷🏻‍♂️ 여기서 발생한 의문!

🤔그냥 물리적인 주소를 각각 다르게 주면 되는 거 아니야?

→ 가상 주소는 논리적인 주소이다.

→ 가상 주소를 사용하면 여러 프로세스들이 메모리를 공유할 수 있다. 물리적 메모리의 용량보다 더 많은 가상 주소를 가진 프로세스들이 동시에 실행될 수 있으며, 가상 주소를 물리적 주소로 매핑함으로써 메모리를 효율적으로 사용할 수 있다.

🤬 이게 뭔 소리냐?

아니, 가상 주소는 프로세스가 각각의 가상 주소 공간을 가지며 서로의 공간에 영향을 미치지 않고 독립적으로 사용할 수 있게 한다고 했잖아… 그런데 메모리를 공유한다는 건 무슨 소리야 도대체?

📤 그럼 한번 예시를 들어보자

프로세스 A와 B가 있다. 이들은 물리적 메모리의 용량보다 크다. 이때 가상 주소로 해결하는 방법을 알아보자.

→ 가상 주소를 사용하여 메모리를 효율적으로 관리하기 위해서 운영 체제는 물리적 메모리를 효율적으로 활용해야 한다.

1. 가상 주소 공간 할당:

운영 체제는 각 프로세스 A와 B에게 가상 주소 공간을 할당한다.

각 프로세스는 자신만의 가상 주소 공간을 갖게 된다

2. 물리적 메모리 공간 관리 :

물리적 메모리에는 실제 데이터와 프로그램 코드가 저장되므로 모든 가상 주소를 물리적 주소로 직접 할당할 수는 없다.

3. 페이지 기반 가상 메모리 관리:

대부분의 운영 체제는 페이지 기반의 가상 메모리 관리를 사용하여 가상 주소와 물리적 주소 간의 매핑을 수행한다. 가상 메모리를 작은 크기의 페이지로 나누고, 물리적 메모리도 동일한 크기의 페이지로 나눈다.

4. 페이지 테이블:

각 프로세스마다 페이지 테이블이라는 자료구조를 유지한다.

  • 페이지 테이블이란 페이지 테이블은 가상 주소의 각 페이지가 실제 물리적 메모리의 어떤 페이지와 매핑되는지를 기록한다. 프로세스가 가상 주소를 참조하면 페이지 테이블을 사용하여 해당 가상 주소를 물리적 주소로 변환한다
    • 페이지 번호(Page Number): 가상 주소에서 페이지 번호를 식별하는 부분
    • 페이지 프레임 번호(Page Frame Number): 물리적 메모리에서 페이지가 위치하는 프레임 번호를 기록
    • 기타 제어 비트(Control Bits): 페이지에 대한 다양한 제어 정보를 포함한다 예를 들어 해당 페이지가 물리적 메모리에 들어가졌었는지의 여부, 수정 가능한 페이지인지 등을 나타낼 수 있따.

가상 주소에 의해 주소가 지정된 페이지와 물리 메모리의 페이지 간의 관계 (단순한 주소 공간 스킴에서) 물리 메모리는 수많은 프로세스에 속하는 페이지를 포함할 수 있다. 거의 사용하지 않을 경우 페이지는 디스크에 보관할 수 있으며, 물리 메모리가 꽉차 있으면 위의 그림처럼 일부 페이지는 물리 메모리에 위치하지 않는다.

(이미지 출처: 위키백과)

5. 페이지 폴트

프로세스가 처음으로 해당 페이지를 접근할 때 물리적 메모리에 해당 페이지가 없는 경우 페이지 폴트가 발생

  • 페이지 폴트란? → 즉, 프로세스가 요청한 페이지가 현재 물리적 메모리에 올라와 있지 않을 때 발생 → 이 경우 운영체제는 해당 페이지를 물리적 메모리로 가져와야 함
    • 프로세스가 페이지 폴트를 발생시키면, 운영 체제는 먼저 해당 페이지가 디스크에 저장되어 있는지 확인한다
    • 만약 해당 페이지가 디스크에 저장되어 있다면, 디스크에서 가져온다
    • 가져온 페이지를 물리적 메모리에 적재하고, 페이지 테이블을 업데이트하여 해당 가상 주소가 새로운 물리적 주소와 매핑되도록 한다
    • 이후에 다시 참조해보면 데이터나 코드에 접근할 수 있다

6. 페이지 교체

물리적 메모리 공간이 가득 찬 경우, 운영 체제는 페이지 교체 알고리즘을 사용하여 더 이상 사용되지 않는 페이지를 디스크로 옮기고 새로운 페이지를 메모리에 로드한다.

→ 이렇게 함으로써 물리적 메모리에 가상 주소 공간을 연결할 수 있다

7. 다중 프로그래밍과 스와핑

다중 프로그래밍 환경에서는 여러 개의 프로세스가 동시에 실행된다. 만약 모든 프로세스가 동시에 물리적 메모리에 올라갈 수 없는 경우, 운영 체제는 스와핑 기법을 사용하여 현재 실행 중인 프로세스의 일부를 디스크로 내보내고, 새로운 프로세스를 메모리에 로드함으로써 다른 프로세스로 전환한다.


후기

변수가 어디에 할당되는지 찾다가 많은 것을 알게 된 공부였다.
실제 메모리보다 더 쓰는 방식으로 저러한 방식을 채택한 개발자들이 정말 대단해 보였고 나 또한 저렇게 시대를 이끌어가는 개발자가 되고 싶었다.

300x250
728x90
728x90

이 글은 <모던 자바스크립트 딥 다이브> 라는 책을 읽고 필자가 재구성하여 작성한 글입니다.

데이터 타입의 필요성

데이터 타입은 왜 필요한 것인가?

🙋‍♀️ : 데이터 타입에 의한 메모리 공간 확보와 참조를 위해

값은 메모리에 저장하고 참조할 수 있어야 한다. 메모리에 값을 저장하려면 먼저 확보해야 할 메모리의 크기를 결정해야 한다.

이렇게 숫자 타입 값이 할당된다.

자바스크립트는 숫자 타입의 값을 생성할 때 배정밀도 64비트 부동소수점 형식을 사용한다. 따라서 실제로 메모리에 저장되는 2진수 값은 위 그림과 다른다. 지금은 간단히 양의 정수로 저장된다고 생각하자

→ 64비트 부동소수점 형식에 관해서는 이전에 다뤄보았다.

🤔 : 값을 생성할 때? 명확한 기준이 없어 조금 헷갈리는걸??

→ 값을 생성할 때란 무엇인가???

프로그램이 실행되는 동안 변수에 할당되거나, 연산이 이루어지거나, 함수가 실행되면서 새로운 값을 만든다는 것을 의미

→ 변수를 선언하고 값을 할당하는 경우

→ 연산을 수행하는 경우

→ 함수를 실행하는 경우

즉 “자바스크립트에서 값을 생성한다” 는 것은 프로그램이 동작하면서 새로운 값을 만들고 변수에 저장하거나 결과로 반환하는 행위를 말한다.

🤷 : 자바스크립트에서 참조한다는 것은?

  • 변경이 가능한 값의 의미이다
  • 객체를 가리키는 변수를 다른 변tn 에 할당하면 원본의 참조 값이 복사되어 전달된다.

자바스크립트에서 참조(Reference)는 변수가 객체나 배열과 같은 데이터 구조에 대한 메모리 주소를 가리키는 것을 의미한다. 다른 말로 하면, 참조는 실제 데이터가 위치한 메모리 영역에 직접 접근하는 것이 아니라, 데이터가 위치한 주소를 통해 해당 데이터에 접근하는 방법을 제공한다.

객체를 선언하여 생성한다

const originalObject = {name : "insidepixce", age : 20};

변수 object가 originalObject를 가리킨다

const referenceObject = originalObject;

referenceObject를 통해 Originalobject의 속성에 접근하고 수정한다

referenceObject.age = 21;

이때 originalObject와 referenceObject는 같은 객체를 가리키고 있다. 따라서 ‘referenceObject’를 통해 해당 객체의 속성을 수정하면 Original Object속의 속성도 같이 변경된다. 이는 객체의 데이터가 복사되지 않고 메모리 주소를 공유하기 떄문이다.

  • 참조는 배열에서도 마찬가지로 동작한다

즉, 식별자를 통해 메모리 공간의 주소를 찾아가는 것이다. 이때 값을 참조하려면 한번에 메모리를 몇 개를 읽어들여야 할지, 즉 메모리 셀의 개수(바이트 수)를 알아야 한다.

🙄 : 그럼 식별자 컴퓨터는 한 번에 읽어 들여야 할 메모리 셀의 크기를 어떻게 알 수 있는가?

🙆‍♀️ : 심벌 테이블이요!

컴파일러 또는 인터프리터는 심벌 테이블이라고 부르는 자료 구조를 통해 식별자를 키로 바인딩된 값의 메모리 주소, 데이터 타입, 스코프 등을 관리한다.

🤦‍♂️ : 그래서 심벌 테이블이 뭐냐고?

컴파일러와 인터프리터 등의 프로그래밍 언어 처리 시스템에서 식별자를 관리하는 자료구조.

심벌 테이블은 각 식별자에 대해 이름과 해당 식별자가 사용되는 메모리 주소 또는 다른 정보를 매핑한다.

인터프리터는 식별자를 사용할 때 해당 식별자가 선언되었는지, 어떤 타입인지, 어느 범위에서 유효한지 등을 파악해야 한다. 이러한 정보는 실행 중인 프로그램에서 변수나 함수를 사용할 때 식별자가 가리키는 정확한 메모리 주소를 알고 있어야 하기 때문이다.

심벌 테이블은 이러한 정보를 저장하고 유지 관리하는 역할을 한다. 컴파일러 또는 인터프리터는 소스코드를 분석하면서 식별자를 발견하면 해당 식별자와 관련된 정보를 심벌 테이블에 추가하거나 참조한다.

→ 일반적으로 해시 테이블 또는 기타 효율적인 데이터 구조를 사용하여 구현됨

→ 언어마다 다름

🌈 그래서 요약하자면!

프로그래밍 언어 처리 시스템에서 식별자를 관리하고, 해당 식별자의 정보를 저장하고 유지 관리하는 자료구조. 이를 통해 변수와 함수 등의 식별자를 정확하게 해석하고 프로그램을 올바르게 처리할 수 있다.

🌷 동적 타입 언어와 정적 타입 언어

자바스크립트의 모든 값은 데이터 값을 가진다.

🤔 : 그렇다면 변수는 데이터 타입을 가질까?

정적 타입 언어는 변수의 타입을 변경할 수 없으며, 변수에 선언한 타입에 맞는 값만 할당할 수 있음

→ 컴파일 시점에 타입체크 진행

→ 선언한 데이터 타입에 맞는 값을 할당했는지 보는 검사임

→ 이 검사 통과 못하면 실행 자체를 막음

타입의 일관성을 강제함으로서 더욱 안정적인 코드의 구현을 통해 런타임에 발생하는 에러를 줄인다

c, c++, 자바, 코틀린, 고, 하스켈, 러스트 , 스칼라 등등…

동적 타입 언어는 변수의 타입을 변경할 수 있으며, 변수에 할당된 값의 타입에 따라 실행 시점에 타입이 결정된다.

→ 변수의 타입을 설정하지 않고 값을 할당할 수 있음

→ 실행 도중에 변수의 타입이 자주 변경될 수 있음

→ 이로 인해 버그 발생 가능성이 높아짐

정적 타입 언어와 달리, 실행 시점에 타입이 결정되므로 타입 에러가 발생하기 쉽다. 따라서 개발자는 변수의 타입을 주의깊게 관리하고, 코드를 작성할 때 타입 에러를 방지할 수 있는 방법을 찾아야 한다.

typeof 연산자는 연산자 뒤에 위치한 피연산자의 데이터 타입을 문자열로 반환한다

var foo;
console.log (typeof foo);

foo = 3;
console.log (typeof foo);

이런식으로 실행할 수 있다.

자바스크립트의 변수에는 어떤 데이터 타입의 값이라도 자유롭게 할당할 수 있다

→ 값을 할당하는 시점에 변수의 타입이 동적으로 결정뙤고 변수의 타입을 언제든지 자유롭게 변경할 수 있다

💯  자바스립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론) 되며,
재할당에 의해 변수의  타입은 언제든지 동적으로 변할 수 있다.

이러한 특징을 동적 타이핑이라고 하며, 자바스크립트를 정적 타입 언어와 구별짓기 위해 동적 타입 언어라고 한다. 대표적인 동적 타입 언어로는 자바스크립트, 파이썬, PHP, 루비, 리스프 , 펄 등이 있다.

이쯤 되어 아까 했던 질문으로 돌아가 보자

🤔 : 그렇다면 변수는 데이터 타입을 가질까?

→ 기본적으로 변수는 타입을 갖지 않는다. 하지만 값은 타입을 갖는다.

따라서 현재 변수에 할당되어 있는 값에 의해 변수의 타입이 동적으로 결정된다고 표현하는 것이 더 적절하다.

변수는 값에 묶여 있는 값에 대한 별명이기 때문이다.

🌷 동적 타입 언어와 정적 타입 언어

동적 타입 언어는 변수에 어떤 값이라도 자유롭게 할당할 수 있다.

자바스크립트를 사용하다 보면 따로 변수 할당을 안 해줘도 원하는 타입으로 사용할 수 있기 때문에 이는 데이터 타입에 무감각해질 정도로 편리해진다.

그렇지만 편리함에 이면에는 위험도 있다.

모든 소프트웨어 아키텍쳐에는 트레이드오프가 존재하며, 모든 애플리케이션에 적합한 은 탄환은 없듯이 동적 타입 언어 또한 구조적인 단점이 있다

Trade-off = 두 개의 정책이나 목표 중 하나를 달성하고자 하면 다른 목표의 달성이 늦어지거나 희생되는 모순적 관계를 의미함.

은 탄환: 아마 고질적인 문제를 단번에 해결할 수 있는 명쾌한 해결책…정도를 의미한듯

변수 값은 언제든지 변경될 수 있기 때문에 복잡한 프로그램에서는 변화하는 변수 값을 추적하기 어려울 수 있다. 변수의 타입이 고정되어 있지 않고 동적으로 변한다.

→ 동적 타입 언어의 변수는 값의 변경에 의해 타입도 언제든지 변경될 수 있다.

  💯 따라서 **동적 타입 언어의 변수는 값을 확인하기 전**에는 타입을 확신할 수 없다.

개발자의 의도와는 상관없어 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다.

잘못된 예측에 의해 오류를 뿜어내는 프로그램을 본다면… 🤦‍♀️

결국 동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다

🙋‍♀️ 안정적인 프로그램을 만들고 싶어요!

  • 변수는 꼭 필요한 경우에 한해 제한적으로 사용한다
  • 변수의 유효 범위는 최대한 좁게 만들어 변수의 부작용을 억제해야 한다
  • 전역 변수는 최대한 사용하지 않도록 한다
  • 변수보다는 상수를 사용해 값의 변경을 억제한다
  • 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.

사실 변수 오류는 그닥 많이 겪어보지 않았다. 내가 초보 개발자이며 아직 경험이 많이 없어서 그런지는 모른다. 하지만 책을 공부하다가 한번쯤은 정리해놓고 싶은 부분이라 작성해보았다.

300x250

+ Recent posts