객체 (Object)

객체는 자바스크립트에서 데이터를 구조화하고 저장하는 방식 중 하나로 키와 값 쌍의 집합으로 구성된다. 이 키-값 쌍을 통해서 다양한 테이터와 기능을 하나의 단위로 묶어 관리할 수 있다.

 

특징

키-값

키는 문자열 또는 심볼이어야 하며 값은 어떠한 데이터 타입도 가능하다. 만약 키에 숫자를 입력할 경우 자동으로 문자로 변환된다.

 

중첩 가능

객체의 값으로 또 다른 객체를 가질 수 있다. 이를 통해 복잡한 데이터 구조를 표현하는 것이 가능하다.

 

동적 속성 추가/제거

객체는 생성된 이후에도 속성을 동적으로 추가하거나 삭제할 수 있다.

 

생성 방법

1. 객체 리터럴

가장 일반적인 객체 생성 방법으로 중괄호를 사용하여 키-값 쌍을 정의한다.

const person = {
    name: 'Bak',
    age: 25,
    greet: function() {
        console.log('Hello, my name is ' + this.name);
    }
};

 

2. 객체 생성자

new Object() 구문을 사용하여 객체를 생성할 수 있다. 이후 점 표기법 또는 대괄호 표기법을 사용하여 속성을 추가한다.

const person = new Object();
person.name = 'Bak';
person.age = 25;
person.greet = function() {
    console.log('Hello, my name is ' + this.name);
};

 

3. 생성자 함수

특정 구조를 가진 객체를 반복해서 생성할 때 유용하다.

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        console.log('Hello, my name is ' + this.name);
    };
}

const alice = new Person('Bak', 25);

 

4. 클래스(ES6 이후)

클래스를 사용하면 객체 지향 프로그래밍의 패턴을 쉽게 구현할 수 있다.

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    greet() {
        console.log('Hello, my name is ' + this.name);
    }
}

const alice = new Person('Alice', 25);

 

객체 사용법 

const game = {
    company: 'Bethesda',
    title: 'Fallout',
    year: 1997
};

// 속성 접근
console.log(game.company); // 'Bethesda'
console.log(game['title']); // 'Fallout'

// 속성 수정
game.year = 2008;
console.log(game.year); // 2008

// 속성 추가
game.series = 'Fallout : New Vegas';
console.log(game.series); // 'Fallout : New Vegas'

// 속성 삭제
delete company.title;
console.log(company.title); // undefined

 

배열 (Array)

배열은 자바스크립트에서 여러 개의 데이터를 순차적으로 저장할 수 있는 자료구조이다. 동일한 타입 또는 서로 다른 타입의 데이터를 모두 저장할 수 있으며 각 데이터는 인덱스로 접근할 수 있다.

 

특징

인덱스 기반

배열의 각 요소는 0부터 시작하는 인덱스를 통해 접근할 수 있다.

 

동적 크기

자바스크립트의 배열은 동적 크기를 가지며, 요소를 추가하거나 제거할 수 있다.

 

다양한 데이터 타입

배열의 요소는 숫자, 문자열, 객체, 다른 배열 등 어떤 데이터 타입도 될 수 있다.

 

배열 생성 방법

1. 배열 리터럴 

가장 일반적인 배열 생성 방법으로 대괄호를 사용하여 배열 요소를 정의한다.

const numbers = [1, 2, 3, 4, 5];
const mixedArray = [1, 'two', {three: 3}, [4, 5]];

 

2. 배열 생성자

new Array() 구문을 사용하여 배열을 생성할 수 있다.

const numbers = new Array(1, 2, 3, 4, 5);
const emptyArray = new Array(10); // 길이가 10인 빈 배열 생성

 

배열 사용법

const fruits = ['apple', 'banana', 'cherry'];

// 요소 접근
console.log(fruits[0]); // 'apple'
console.log(fruits[1]); // 'banana'

// 요소 수정
fruits[1] = 'blueberry';
console.log(fruits[1]); // 'blueberry'

 

인덱스로 배열의 요소에 접근하여 사용할 수 있다.

 

 

배열 메서드

자바스크립트 배열은 다양한 메서드를 통해 요소를 추가, 제거, 탐색, 변형할 수 있다.

 

1. push

push 메서드는 배열의 끝에 하나 이상의 요소를 추가하고 배열의 새로운 길이를 반환한다.

const fruits = ['apple', 'banana'];
let len = fruits.push('orange');
console.log(len); // 3
console.log(fruits); // ['apple', 'banana', 'orange']

.

2. pop

pop 메서드는 배열의 마지막 요소를 제거하고 그 요소를 반환한다.

const fruits = ['apple', 'banana', 'orange'];
const lastFruit = fruits.pop();
console.log(fruits); // ['apple', 'banana']
console.log(lastFruit); // 'orange'

 

push & pop 사용 예제

const fruits = ['apple', 'banana'];

// push: 배열 끝에 요소 추가
fruits.push('cherry');
console.log(fruits); // ['apple', 'banana', 'cherry']

// pop: 배열 끝의 요소 제거
const lastFruit = fruits.pop();
console.log(fruits); // ['apple', 'banana']
console.log(lastFruit); // 'cherry'

 

3. map

map 메서드는 배열 내의 모든 요소에 대해 제공된 함수를 호출한 결과로 새로운 배열을 생성한다.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(num => num * num);
console.log(squared); // [1, 4, 9, 16, 25]

 

4. filter

filter 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

 

5. reduce

reduce 메서드는 배열의 각 요소에 대해 주어진 reducer 함수를 실행하여 단일 값을 반환한다.

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15

 

reduce는 배열의 각 요소를 순회하며, 콜백 함수의 결과를 누산 하여 단일 값을 생성한다. 여기서 

(acc, curr) => acc + curr는 콜백함수로 두 개의 주요 인수를 받는다.

 

acc : 이전 콜백에서 반환된 값으로 이전 인덱스까지 누산 된 값

curr : 현재 순회 중인 인덱스의 요소

 

(콜백함수), 0 : 0이 초기값으로 이 값을 시작으로 요소의 값들이 누산 되기 시작한다.

 

공식 문법은 다음과 같다.

arr.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)

 

실제 필요한 인수들이 다양한 방식으로 표기가 가능한데 그 이유는 자바스크립트의 함수 인수 처리 방식 때문이다.

 

자바스크립트에서는 함수가 호출될 때 정의된 인수보다 더 많은 인수가 전달되면 무식하고, 더 적은 인수가 전달되면 undefined로 처리한다.

 

따라서 reduce 메서드에서 필요한 인수만이 알아서 사용된다.

 

따라서 생략형 콜백에서는 첫 번째와 두 번째 인수만 사용하며 두 값을 합한 결과만 리턴하기로 한다.

 

이 과정이 반복되면서 전체 요소의 합산이 되는 것이다.

 

모든 인수를 적용해서 호출하면 다음과 같다.

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, currentValue, currentIndex, array) => {
    console.log('Accumulator:', accumulator);
    console.log('Current Value:', currentValue);
    console.log('Current Index:', currentIndex);
    console.log('Array:', array);
    return accumulator + currentValue;
}, 0);

console.log('Sum:', sum); // Sum: 15

 

인수 (accumulator, currentValue, currentIndex, array) => {콜백 함수} : 요소의 누산 값을 반환

auccumulator : 누산값

currentVlaue : 현재 요소값

currnetIndex : 현재 인덱스

array : 참조 배열

 

 

 

728x90
반응형

Visual Studio 2022

 

class 생성

멤버변수 int 하나

public class Test
{
	int data_1;
}

public static void Main(string[] args)
{
	Test test = new Test();
}

C# Class Size Test (Field int 1)

int 하나인데 크기가 24 바이트이다.

int = 4byte 인데 왜 6배나 되는걸까?

=>6개 이상일 때 크기 확인 해보기로함

public class Test
{
	public int data_1;
	public int data_2;
	public int data_3;
	public int data_4;
	public int data_5;
	public int data_6;
}

일단 int 6개로 테스트, 기대 결과는 그대로 24byte

C# Class Size Test (Field int 6)

이게 무슨일이지, 40 byte 가 나옴

처음 결과를 기준으로 생각해보면 24 + 16 즉 16 byre가 추가됨.

4(int) * 4(count) 라고 생각해보고 다시 필드를 int * 3으로 테스트

 

public class Test
{
    public int data_1;
    public int data_2;
    //public int data_3;
    //public int data_4;
    //public int data_5;
    //public int data_6;
}

예상한대로면 처음 결과인 24가 나와야함

C# Class Size Test (Field int 2)

결과는 기대한대로 나왔지만 여전히 24라는 크기가 이해가 안감,

혹시나해서 클래스를 인스턴스화 안했을때 한번 확인해봤지만 당연하게 해당 메모리 안잡힘

 

이번엔 하나씩 필드 늘려가면서 확인해보기로함

C# Class Size Test (Field int 3)

int * 4 일때는 동일하게 32

C# Class Size Test (Field int 5)

int * 5 부터 40 으로 잡혔음

 

그럼 그냥 빈 클래스는 얼마로 잡히나 확인했는데

애초에 비어있는 클래스를 인스턴스하면 24 byte 할당됨

여기서 2개씩 int 추가될 때마다 8 byte가 늘어나는데 이 늘어나는 값은 4(int) * 2(count) 맞음

 

비어있는 클래스가 왜 24 byte의 힙을 차지하는지 파악해보면될듯함

일단 Program 외부에 Test_2 클래스, 내부에는 Test_1 선언 후 비교

public class Test_2 { }
public class Program
{
    public class Test_1 { }
    public static void Main(string[] args)
    {
        Test_1 test_1 = new Test_1();
        Test_2 test_2 = new Test_2();
    }
}

C# Class Size Test_1 / Test_2 (empty)

테스트 해본 결과 클래스를 할당하면 기본 크기가 24로 잡히고 이 안에 8byte 까지는 포함시킬 수 있는걸로 보인다.

즉 기본 24 = 16(사용됨) + 8(여유 공간) 이고 크기가 24 byte를 넘을 경우 8byte 단위로 확장되는걸로 파악됨

 

구글링 해본 결과 내가 원하는 정보를 찾을 수 있었다.

 

OF MEMORY AND STRING_Jon Sket

 

본래 글의 취지는 .Net에서 ASCII 문자열의 효율적인 표현에 관한것에 대한 답이다.

위 글에서는 x86과 x64를 모두 비교하고 있는데 이 글에서는 x64를 기준으로 정리한다.

 

그럼 이제 왜 0byte는 될수없는지 그리고 24byte 중 사용할 수 없는 16byte와 사용 가능한 8byte는 무엇 때문인지 정리한다.

 

우선 C#에서 모든 타입은 object 타입을 베이스로한다. 그리고 이 object 타입의 크기는 24byte이다.

이 24byte의 크기는 16byte의 오버헤드와 참조를 위한 8byte로 이루어진다. 

 

오버헤드란 처리를 하기 위해 들어가는 간접적인 처리 시간, 메모리 등을 말한다. 즉 C#의 object를 메모리에 유지시키는데 필요한 메모리 양이 16byte이며 .Net의 CLR은 데이터가 없는 object에서 작업할 수 없기 때문에 오버헤드만 가지고는 object를 사용할 수 없고 여유 공간이 필요하며 이 크기가 8byte이다. 따라서 선언될 수 있는 가장 작은 크기의 메모리는 24byte가 된다.

 

이 중 여유공간인 8byte는 실제 데이터를 저장할 수 있기 때문에 int가 2개 포함된 class역시 24byte였다. 이 8byte는 전체를 사용할 수 있는 공간이기 때문에 1byte로 8를 사용하는것도 가능하다. 그리고 int가 3개가 될때 24byte에서 8byte로 증가했는데 이것은 메모리의 경계인 패딩의 크기가 8byte였기 때문이다. 

 

class 역시 object 타입을 베이스로 하고 있고 빈 class를 인스턴스화 하는것은 object를 생성하는것과 마찬가지이기 때문에 빈 class가 24byte라는것도 이제 납득이 간다. 

 

오버헤드에 대한 내용

overhead - Andrew Hunter
overhead - Stack Overflow

 

왜 이렇게 많은 공간이 필요한지 또 이 공간은 어떤식으로 사용되는지 궁금한데 이 부분은 더 자세히 찾아봐야 될것같다.

 

정리

64bit 기준으로 

1. 비어있는 class 또한 하나의 object이다. 따라서 24byte 메모리를 차지한다.

2. 이 메모리는 16byte의 내부 데이터 참조형으로 사용되는 오버헤드와 8byte의 여유공간으로 구성된다.

3. 여유공간은 모두 사용이 가능하며 메모리는 8byte의 패딩을 가지고 있다.

 

728x90
반응형

'Memo' 카테고리의 다른 글

다국어를 제공하는 방법에 대해서  (0) 2023.05.10

+ Recent posts