브라우저와 서버의 메모리 상태가 새로고침이나 재시작 뒤 사라지는 이유는 무엇인가요?
브라우저와 개발 서버는 서로 다른 실행 공간이며 메모리에 둔 상태도 따로 관리합니다. 새로고침이나 서버 재시작 뒤 값이 사라졌다면 먼저 어디에 저장했는지 확인하세요.
적용 조건·범위: 위 상태는 예시 모델입니다. 실제 앱의 저장 구현, 브라우저 탭과 프로세스의 일대일 관계, 메모리 누수 여부는 검증하지 않았습니다.
공식 문서 참고: Chrome 공식: 프로세스·스레드·메모리와 브라우저 구조 · MDN: 실행 컨텍스트·태스크·마이크로태스크
프로그램과 프로세스
프로그램은 실행할 수 있는 코드와 파일을 의미합니다.
프로세스는 그 프로그램이 실제로 실행되고 있는 상태를 말합니다.
예를 들어 브라우저 설치 파일 자체는 프로그램이고, Chrome을 실행했을 때 운영체제가 관리하는 실행 단위가 프로세스입니다.
프로그램
→ 실행
→ 프로세스
Node.js 개발 서버도 마찬가지입니다.
server.js
→ node server.js 실행
→ Node.js 프로세스 생성
프로세스는 자신의 메모리 공간과 실행 상태를 가집니다.
그래서 브라우저 프로세스와 Node.js 서버 프로세스는 서로 다른 메모리를 사용합니다.
프로세스와 스레드
프로세스 안에서는 실제 작업을 수행하는 스레드가 동작합니다.
간단히 이해하면 다음과 같습니다.
프로세스
→ 실행 중인 프로그램 단위
스레드
→ 프로세스 내부에서 작업을 수행하는 실행 흐름
운영체제와 런타임 내부 구현은 훨씬 복잡하지만 프론트엔드에서 중요한 것은 브라우저 탭의 JavaScript와 서버의 JavaScript가 같은 메모리에서 실행되는 것이 아니라는 점입니다.
브라우저 실행 구조
현대 브라우저는 보안과 안정성을 위해 여러 프로세스를 사용하는 구조를 가질 수 있습니다.
예를 들어 브라우저 UI, 페이지 렌더링, GPU, 네트워크 처리 등이 별도 프로세스로 나뉠 수 있습니다.
다만 브라우저 구현과 상황에 따라 실제 프로세스 배치는 달라질 수 있습니다.
따라서 다음처럼 단정해서 외우면 안 됩니다.
탭 하나 = 항상 프로세스 하나
대신 다음 원칙을 이해합니다.
브라우저는 여러 실행 단위를 사용하며
페이지 코드와 서버 코드는 서로 다른 프로세스 영역에서 실행될 수 있다.
Chrome의 브라우저 작업 관리자나 운영체제 작업 관리자를 보면 브라우저 관련 프로세스가 여러 개 나타나는 것을 확인할 수 있습니다.
JavaScript와 메인 스레드
브라우저 페이지의 일반적인 JavaScript와 DOM 작업은 메인 스레드에서 처리됩니다.
긴 동기 작업이 메인 스레드를 오래 점유하면 클릭이나 렌더링이 늦어져 화면이 멈춘 것처럼 느껴질 수 있습니다.
for (let i = 0; i < 5_000_000_000; i += 1) {
// 오래 걸리는 동기 작업
}
실제 실행 시간은 기기와 환경에 따라 크게 달라집니다.
이런 코드를 실서비스에서 실행하는 것이 목적이 아니라 긴 동기 작업이 UI 반응성을 막을 수 있다는 개념을 이해하기 위한 예입니다.
JavaScript가 항상 모든 환경에서 단일 스레드라고 표현하는 것도 정확하지 않습니다.
브라우저에서는 Web Worker를 이용해 별도 스레드에서 작업할 수 있고, 브라우저 자체도 여러 스레드와 프로세스를 사용합니다.
프론트엔드 학습에서는 다음처럼 표현하는 것이 안전합니다.
일반적인 페이지 JavaScript와 DOM 조작
→ 주로 메인 스레드
Web Worker 등
→ 별도 작업 스레드 사용 가능
stack과 heap
메모리 설명에서 stack과 heap이라는 단어를 자주 봅니다.
초급 단계에서는 엔진 내부 구현을 외우기보다 역할 중심으로 이해합니다.
stack
→ 함수 호출과 실행 흐름을 관리하는 영역으로 설명되는 경우가 많음
heap
→ 객체처럼 동적으로 생성되는 데이터를 저장하는 영역으로 설명되는 경우가 많음
실제 JavaScript 엔진의 메모리 구현은 더 복잡합니다.
따라서 모든 값이 정확히 어디에 저장되는지 암기하는 것보다 참조 관계와 객체 생명주기, 불필요한 데이터가 계속 남는 상황을 이해하는 것이 더 중요합니다.
브라우저 메모리와 서버 메모리
TaskFlow를 예로 보겠습니다.
브라우저 JavaScript 변수입니다.
let tasks = [
{
id: '1',
title: 'CS 공부하기',
completed: false
}
];
이 데이터가 브라우저 페이지 메모리에만 있다면 페이지를 새로고침했을 때 초기화될 수 있습니다.
서버에도 다음처럼 별도 배열이 있을 수 있습니다.
const tasks = [];
이 배열은 서버 프로세스 메모리에 있습니다.
브라우저의 tasks와 서버의 tasks는 이름이 같아도 완전히 다른 메모리입니다.
브라우저 프로세스
tasks
HTTP 요청
↕
서버 프로세스
tasks
서버 프로세스를 재시작하면 서버 메모리의 배열도 사라질 수 있습니다.
그래서 실제 서비스는 중요한 데이터를 DB 같은 영속 저장소에 보관합니다.
메모리와 영속 저장소 구분
상태가 어디에 저장되는지 구분해보겠습니다.
React state
→ 브라우저 JavaScript 메모리
일반 JavaScript 변수
→ 해당 프로세스 메모리
localStorage
→ 브라우저 저장소
IndexedDB
→ 브라우저 저장소
Node.js 전역 변수
→ 서버 프로세스 메모리
데이터베이스
→ 별도 영속 저장소
브라우저 저장소라고 해서 서버 DB와 같은 것은 아닙니다.
localStorage는 특정 브라우저와 origin에 종속되고 사용자가 삭제할 수 있습니다.
DB는 서버나 외부 데이터 서비스가 관리하며 여러 사용자와 기기에서 공유할 수 있도록 설계할 수 있습니다.
서버 재시작 후 상태가 사라지는 이유
개발 중 메모리 배열을 API 저장소처럼 사용하는 경우가 있습니다.
const tasks = [];
app.post('/tasks', (req, res) => {
tasks.push(req.body);
res.json(req.body);
});
서버가 실행되는 동안에는 데이터가 남아 있습니다.
하지만 프로세스를 종료하고 다시 시작하면 tasks 배열은 다시 빈 배열에서 시작합니다.
서버 프로세스 종료
→ 프로세스 메모리 해제
→ 다시 실행
→ 새 메모리 상태
이 때문에 개발용 메모리 데이터는 영속 저장소가 아닙니다.
서버 프레임워크 없이 프로세스 메모리 확인하기
앞의 app.post 조각은 Express 같은 서버에서 app과 요청 본문 처리가 이미 준비됐다고 가정한 부분 예시입니다. 메모리 초기화 개념만 확인하려면 Node.js가 설치된 환경에서 아래 전체 코드를 memory.mjs로 저장합니다. 추가 패키지는 필요하지 않습니다.
const tasks = [];
tasks.push('메모리 실습');
console.log('실행 후:', tasks);
node memory.mjs
node memory.mjs
두 실행 모두 실행 후: [ ‘메모리 실습’ ] 한 항목을 출력합니다. 첫 실행의 배열을 두 번째 프로세스가 이어받지 않기 때문입니다. 같은 파일에서 push 줄을 한 번 더 추가하면 각 실행은 두 항목을 출력합니다. 파일·DB에 저장한 것이 아니므로 실행 횟수만으로 항목이 누적되지 않습니다. 이 예제는 브라우저 저장소나 GC의 실제 메모리 해제를 측정하지 않습니다.
메모리 누수 기본 이해
더 이상 필요하지 않은 객체가 계속 참조되어 메모리에서 제거되지 못하고 사용량이 증가하는 상황을 메모리 누수라고 부를 수 있습니다.
예를 들어 이벤트 리스너나 타이머를 반복 등록하고 정리하지 않는 코드가 원인이 될 수 있습니다.
const timerId = setInterval(() => {
console.log('running');
}, 1000);
// 더 이상 필요하지 않으면 정리
clearInterval(timerId);
모든 메모리 증가가 누수는 아닙니다.
캐시나 현재 필요한 데이터 때문에 사용량이 늘어날 수도 있습니다.
시간이 지나도 불필요한 객체가 계속 남는지 관찰해야 합니다.
자주 하는 오해
브라우저와 서버가 같은 JavaScript 변수에 접근합니다
아닙니다.
브라우저와 서버는 일반적으로 서로 다른 프로세스와 메모리에서 실행됩니다.
데이터를 공유하려면 HTTP·WebSocket·DB 같은 명시적인 통신이나 저장 구조가 필요합니다.
JavaScript는 무조건 단일 스레드입니다
지나치게 단순한 표현입니다.
페이지의 일반적인 JavaScript 실행과 DOM 조작은 주로 메인 스레드에서 이루어지지만 Worker 같은 별도 스레드 기능이 있고 브라우저 자체도 여러 실행 단위를 사용합니다.
localStorage는 서버 데이터베이스입니다
아닙니다.
특정 브라우저 origin에 묶인 클라이언트 저장소입니다.
서버 변수에 저장하면 데이터가 영구 보존됩니다
아닙니다.
프로세스 메모리는 서버 재시작이나 인스턴스 교체로 사라질 수 있습니다.
메모리 사용량이 늘면 무조건 누수입니다
아닙니다.
현재 필요한 데이터나 캐시로 증가할 수 있으므로 시간에 따른 유지·해제 패턴을 확인해야 합니다.
독자 질문과 실전 확인
독자 질문
새로고침 뒤 필터가 사라지는 현상과 서버 재시작 뒤 작업이 사라지는 현상은 같은 메모리 문제일까요?
웹 개발 사례
TaskFlow 필터를 JavaScript 변수로만 보관하면 페이지 새로고침 때 초기화될 수 있습니다. API 서버가 작업 목록을 배열로만 보관하면 서버 프로세스 재시작 때 초기화될 수 있습니다. 두 값은 서로 다른 실행 위치에 있습니다.
직접 확인할 문제
필터 변수, localStorage, 서버의 배열, 데이터베이스를 브라우저 메모리·브라우저 저장소·서버 메모리·영속 저장소로 나눠 적고 각각 새로고침·서버 재시작·다른 기기 접속에서 무엇이 남을지 예측해 보세요.
예상 결과와 판단
브라우저 변수는 새 문서 로드에서 일반적으로 초기화됩니다. localStorage는 같은 origin의 그 브라우저에서 유지될 수 있지만 다른 기기의 서버 DB는 아닙니다. 서버 배열은 프로세스 재시작 시 새로 초기화됩니다. DB의 지속성·공유 범위는 실제 설계와 저장 성공 여부를 확인해야 합니다.
검증 범위
위 상태는 예시 모델입니다. 실제 앱의 저장 구현, 브라우저 탭과 프로세스의 일대일 관계, 메모리 누수 여부는 검증하지 않았습니다.
다음 학습: 7회차에서는 이런 실행 위치와 네트워크 계층을 합쳐 장애를 진단합니다.
학습 완료 체크리스트
- 프로그램과 프로세스를 구분할 수 있습니다.
- 프로세스와 스레드의 기본 역할을 설명할 수 있습니다.
- 브라우저 탭과 서버가 같은 메모리를 공유하지 않는다는 점을 이해했습니다.
- JavaScript 메인 스레드와 Worker를 구분할 수 있습니다.
- 메모리 상태와 영속 저장소를 구분할 수 있습니다.
- 서버 재시작 후 인메모리 데이터가 사라질 수 있는 이유를 설명할 수 있습니다.
- 메모리 증가와 메모리 누수를 무조건 같은 것으로 보지 않습니다.
선택 실습: 같은 프로젝트로 연습하기
이 선택 실습은 TaskFlow의 요청 흐름을 설명하는 분석 노트를 만드는 연습입니다. 실행 앱을 새로 만드는 과정은 아닙니다.
브라우저·서버·영속 저장소 레이어를 추가합니다.
TaskFlow 요청 흐름 분석 노트
이전 체크포인트
cs-step-05-http-cache
현재 상태
TaskFlow 요청 흐름에는 네트워크와 캐시까지 표시되어 있습니다.
하지만 데이터가 어느 실행 주체에 존재하는지는 표시되어 있지 않습니다.
이번 목표
브라우저·서버·영속 저장소 레이어를 추가합니다.
브라우저 프로세스
- 화면 상태
- JavaScript 변수
- localStorage
HTTP
서버 프로세스
- 요청 처리
- 인메모리 상태
↓
영속 저장소
- DB
- 외부 백엔드
상태 위치 표
필터 선택값
→ 브라우저 메모리
브라우저 사용자 설정
→ localStorage 가능
서버 임시 캐시
→ 서버 메모리
공유 Task 데이터
→ DB 같은 영속 저장소
서비스 설계에 따라 실제 위치는 달라질 수 있습니다.
Before
상태가 사라짐
→ 원인을 한 종류로 생각
After
새로고침 후 사라짐
→ 브라우저 메모리 여부 확인
서버 재시작 후 사라짐
→ 서버 인메모리 여부 확인
다른 기기에서 안 보임
→ 클라이언트 로컬 저장소 여부 확인
현재 확장 단계
✓ 1. 브라우저·HTTP 요청/응답
✓ 2. DNS·TCP·TLS
✓ 3. 쿠키·세션·토큰·CORS
✓ 4. CSRF·XSS
✓ 5. HTTP 캐시
→ 6. 프로세스·스레드·메모리
○ 7. 통합 장애 진단
완료 체크포인트
cs-step-06-process-memory
다음 학습
지금까지 요청 경로·인증·보안·캐시·실행 위치를 각각 학습했습니다.
마지막 글에서는 이 내용을 하나의 장애 진단 순서로 합쳐 페이지가 안 열림, API 실패, 로그인 실패, CORS 오류, 오래된 화면 같은 문제를 계층별로 찾는 방법을 정리합니다.
다음 글: 웹 요청 장애 진단: DNS·HTTP·CORS·인증·캐시 문제를 계층별로 찾기
글 소개·학습 준비·전체 목차

CS 기초 · 6 / 7 · 필수 학습 · 프로세스와 메모리
프론트엔드 개발을 하다 보면 브라우저 탭을 새로고침했더니 상태가 사라지거나, 개발 서버를 재시작했더니 데이터가 초기화되는 상황을 만납니다.
이때 브라우저와 서버를 하나의 프로그램처럼 생각하면 원인을 구분하기 어렵습니다.
이번 글에서는 프로세스·스레드·메모리의 최소 개념을 이용해 코드가 어디에서 실행되고 상태가 어디에 존재하는지 구분합니다.
이번 글에서 배우는 내용
- 프로그램과 프로세스 차이
- 프로세스와 스레드의 기본 개념
- 브라우저가 여러 프로세스를 사용할 수 있다는 점
- JavaScript 메인 스레드와 Worker의 관계
- stack과 heap의 역할 중심 개념
- 브라우저 메모리와 서버 메모리 차이
- localStorage·DB와 메모리의 영속성 차이
- 서버 재시작 후 상태가 사라지는 이유
- 메모리 누수의 기본 의미
선수 지식
- 브라우저와 서버가 HTTP로 통신한다는 개념
- JavaScript 코드가 브라우저에서 실행될 수 있다는 기본 이해
- 서버가 별도 프로그램으로 실행될 수 있다는 이해
목차
이 글이 도움이 되었나요?
읽음 기록
읽음 — / 전체 7개 · 필수 7개
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.