본문 바로가기

CS study/java

자바 객체의 메모리 사용량 및 오버헤드

목차

    개요

     

    주말에 알고리즘을 풀다가 든 궁금증을 정리하였다.

     

    일반적으로, 우리는 구현이나 시뮬레이션, 그것이 아니더라도 Java 기반의 문제 풀이라면 여러 자료구조 및 커스텀 클래스를 사용하게 된다. (Comparable이라던지.. )

     

    뭐 이런 2차원 배열을 이용하는 등의 좌표라던지.

     

    그리고 이 좌표를 표현하는 데에는 크게 두 가지 방법을 많이 사용하는 듯하다.

    import java.io.*;
    import java.util.*;
    public class Main {
    
    	public static void main(String[] args) throws Exception {
    		int[] pos = {1, 2}; //특정 좌표를 배열로 표현하거나,
    		Pos posClass = new Pos(1, 2); //혹은 이런 식으로 객체 타입으로 표현할 수도 있을 것이다.
    	}
    }
    class Pos {
    	int r, c;
    	public Pos(int r, int c) {
    		this.r = r;
    		this.c = c;
    	}
    }

     

    일반적으로 기본 배열이 훨씬 효율적이기는 하지만, 가독성 측면이나 여러 메서드 등에서 참조값을 입력 Parameter로 지정, 혹은 자료구조의 입력값으로 넣을 때 Class 변수가 더욱 편리한 것은 확실하다.

     

    하지만 문제에서 메모리 제한이나 시간 제한이 있어 항상 이것을 사용해도 되나 고민이 많았는데, 이번에 메모리 크기를 정리해보고자 한다.

     

    위와 같이, int 배열과 커스텀 클래스라고 가정해보자.

    기본 배열(int[2]) 사용시 메모리 사용량

    • int 타입은 4바이트(32비트)를 사용한다.
    • 따라서 int[2]는 4바이트 × 2 = 8바이트를 사용한다.
    • 배열 객체 자체에 대한 오버헤드가 있다. 자바에서 배열 오버헤드는 일반적으로 12바이트 정도이다. (대략적인 수치)
    • 총 사용량은 대략 8 + 12 = 20바이트가 될 것이다.

    Mark word와 Pointer의 오버헤드

     

    Mark Word: 객체의 상태 정보를 담고 있는 메모리 영역

    Klass Pointer: 객체의 클래스 메타데이터에 대한 포인터

    사용자 정의 클래스(Pos) 사용시 메모리 사용량

    • Pos 객체에는 두 개의 int 필드가 있다. 각각 4바이트이므로 총 8바이트를 사용한다.
    • 객체 오버헤드도 고려해야 한다. JVM(Java Virtual Machine)에 따라 다르지만, 대략 12바이트에서 16바이트 정도이다.
    • 따라서 총 사용량은 8 + 12(또는 16) = 20(또는 24)바이트가 될 것이다.

    예를 들어, Integer Wrapper 클래스는 자체적으로 4바이트지만, 오버헤드를 고려하면 16바이트일 것이다. 

    비교

    두 방법의 메모리 사용량은 비슷하지만, Pos 클래스를 사용하는 것이 약간 더 많은 메모리를 사용할 수 있다. 객체 지향적 접근의 추가 오버헤드가 있기 때문이다.

     

    메모리 사용량에 대한 정확한 계산은 JVM의 구현과 객체를 관리하는 방식에 따라 달라질 수 있다.

    현대의 JVM은 다양한 최적화 기법을 사용하여 메모리 사용을 관리하므로, 위 계산은 근사치에 불과하다는 점을 이해해야 한다.

     

    결론적으로, Pos 객체를 사용하는 것이 약간 더 많은 메모리를 사용하지만, 코드의 가독성과 유지보수성을 고려할 때 Pos를 사용하는 것은 적절하다고 생각된다.

     

     

    ref

    https://dzone.com/articles/whats-wrong-with-small-objects-in-java

     

    What's Wrong With Small Objects in Java? - DZone

    Small objects can become a burden in a Java app due to their fixed per-object overhead, which is comparable to their ''payload'' and, therefore, reduces memory.

    dzone.com

     

     

    https://tangoblog.tistory.com/14

     

    java가 메모리를 할당하는 방법 (객체 크기 계산)

    개요 C/C++의 sizeof() 함수가 있는 것과 달리 Java에서는 Object 크기를 정확하게 측정할 수 있는 방법이 없습니다. 메모리상에 대규모의 데이터를 Cache용도로 저장하여 최대한 성능을 향상시키고자

    tangoblog.tistory.com

     

    https://stackoverflow.com/questions/2972578/how-calculate-java-array-memory-usage

     

    how calculate java array memory usage

    If I have: int c[] = new int[10]; and int a[][] = new int[2][3]; and in generally an n*m*..*j array how can I calculate the real memory usage considering also the references variables?

    stackoverflow.com

     

     

    How to calculate the memory usage of a Java array

    How to calculate the memory usage of a Java array Following on from our discussion of the memory usage of Java objects, on this page, we consider the special case of arrays. Recall that: in Java, an array is a special type of object; a multi-dimensional ar

    www.javamex.com