c에서는 메모리 관리를 따로 해야한다는데 그게 무슨 말인가요?

java에서는 메모리 관리를 알아서 해준다고 하고 c에서는 본인이 따로 관리해줘야 한다고 하더라구요.

따로 관리를 해줬을 때의 장점이 있어서 그런건가요? 제 상식으로는 자동으로 관리해주는게 좋으면 좋았지 나쁘지는 않을거 같은데 c에서는 왜 안되는 건가요?

    2개의 답변이 있어요!

    • C언어에서는 malloc 함수로 메모리를 할당받고 free 함수로 직접 해제합니다.

      예를 들어서 숫자를 입력받아서 거꾸로 출력하는 프로그램이라면

      import java.util.Scanner; public class Main { public static void main(String... args) { Scanner sc = new Scanner(System.in); int arr[] = new int[sc.nextInt()]; for(int i = 0; i < arr.length; i++) { arr[i] = sc.nextInt(); } for(int i = arr.length - 1; i >= 0; i--) { System.out.print(" " + arr[i]); } } }

      자바로 만들면 이렇게 됩니다. new로 메모리를 할당받고, 따로 해제하지 않습니다.

      #include <stdio.h> #include <stdlib.h> int main() { int len, i; scanf("%d", &len); int *arr = malloc(sizeof(int) * len); // 여기서 할당받고 for(i = 0; i < len; i++) { scanf("%d", &arr[len]); } for(i = len - 1; i >= 0; i--) { printf(" %d", arr[len]); } free(arr); // 여기서 해제합니다. return 0; }

      하지만 C로 만들면 이렇게 free로 메모리를 직접 해제합니다.

      기본적으로 메모리를 할당받으면 해제를 해야 합니다. 사용하지 않는 메모리는 해제되어야 합니다.

      자바도 메모리를 해제하긴 하는데, 메모리를 프로그래머가 직접 해제하지는 않고 가상머신이 알아서 해제해 줍니다.

      자바 가상머신이 할당받은 모든 메모리를 감시한다고 하면 이해가 쉬우려나요? Garbage Collector(이하 GC)로요.

      아무도 참조하지 않는, 쓰레기 메모리가 되는 걸 확인하면 그 때 메모리를 해제합니다.

      아무도 참조하지 않는다는 걸 모두 실시간으로 알 수 있는 건 아니고, 주기적으로 GC가 돌아서 확인해야 합니다.

      메모리 관리를 알아서 해 준다는 게 GC가 돌아서 확인한다는 것입니다.

      https://12bme.tistory.com/57 https://d2.naver.com/helloworld/1329

      자세한 내용을 원하신다면, 이런 글을 읽어보는 것도 좋을 것 같습니다!

      ※ 정리

      메모리 관리를 알아서 해 주면 코드 짤 때는 메모리를 신경쓰지 않아도 됩니다. 분명한 장점입니다.

      하지만 메모리 관리를 알아서 해 주면 (GC가 돌면서) 성능이 떨어진다는 명백한 단점도 있습니다.

    • 간단히 설명 드리겠습니다.

      먼저 메모리는 무한한 자원이 아니기에 관리를 필요로 합니다.

      메모리를 사용하기 위해서는 OS에 사용을 요청해야 합니다. 이렇게 사용 요청을 하는 것을 메모리를 할당 받다라고 표현합니다.

      그러면 할당 받은 메모리의 사용이 끝난 후 어떻게 해야 할까요? 그냥 내가 무한정 가지고 있으면 될까요? 아니죠 위에서 말했듯이 메모리는 유한한 자원이기 때문에 내가 사용을 하지 않을시 반납을 해야합니다. 반납을 하지 않게 되면 나중에는 메모리가 부족하여 문제가 생기겠죠?

      이렇게 메모리를 반납하는 것을 메모리 관리라고 표현할 수 있습니다.

      그런데 이렇게 메모리를 반납하는 주체가 누구냐에 따라 C와 Java의 차이점이 있습니다.

      C에서는 프로그래머가 직접 free라는 함수를 이용하여 반납을 진행해야 합니다. 만일 free호출이 없으면 절대 반납이 되지를 않습니다.

      하지만 java에서는 GC(Garbage Collector)라고 하는 프로세스(이 말이 어려우면 그냥 하나의 앱이라고 생각하세요. 실제 앱은 아닙니다.)가 스스로 사용하지 않는 메모리를 찾아 반납을 해주고 있습니다.

      이런 상황에서 프로그래머가 일일히 반납을 해줘야 하는 C같은 경우는 조금 불편하죠. 또한 프로그래머가 실수로 메모리 반납을 하지 않으면 메모리 누수(Memory leak, 메모리를 사용하지 않지만 반납이 되지를 않아 그 누구도 사용 못하는 현상)가 발생할 가능성이 높습니다. 이러한 점에서 Java가 장점을 가지고 있죠.

      하지만 java에도 문제가 있습니다. 우선 GC가 동작하기 위해서 다른 프로세스들을 중지하고 GC만이 동작을 해야 합니다. 또한 GC 동작은 가장 우선으로 동작을 하기 때문에 일반적인 프로세스들이 피해를 볼 가능성이 높습니다. 이 피해는 성능 저하를 야기하죠. 즉 느려지죠. 또한 GC도 하나의 프로그램이다보니 에러 가능성이 충분히 존재합이다. 즉 제대로 메모리를 반납하지 못할 가능성도 존재하죠. 이렇기 때문에 Java는 높은 실시간성이 요구되는 시스템에서는 문제가 발생합니다. 실시간으로 처리가 되어야 하는 동작이 있는데 GC동작으로 인해 처리가 안되는 경우죠.

      그렇기 때문에 높은 성능을 요구하는 곳에서는 아직까지 C로 코딩을 해야하는 요구사항이 있습니다. 물론 요즘은 HW 성능이 좋아져 큰문제가 아닐수 있겠지만 매우 짧은 시간이라도 영향을 받는 시스템이 있다면 Java는 사용이 어렵습니다.

      그렇기 때문에 개발하는 애플리케이션의 특징에 따라 C를 선택하기도 하고, Java를 선택하기도 합니다.