Java necə işləyir

Mövzu seç, kod yaz və daxildə nə baş verdiyini addım-addım gör.

Memory

Collection-lar

Concurrency

Dil və JVM

Mövzular

Object yaddaşda

Header: hər object-in 12 byte-ı

Heap-dəki hər object header ilə başlayır. 8 byte mark word, 4 byte isə class pointer-dir, yəni object-in class-ı.

Mark word bir neçə iş görür: identity hash, GC age və kilid vəziyyəti. Hamısı eyni 64 bit-də yerləşir. Kilid tutulanda bu bit-lər pointer-ə çevrilir.

Düymələri bas və bit-lərin necə dəyişdiyinə bax. Java 18-dən biased locking yoxdur, ona görə burada da göstərilmir.

Field-lər və padding

Field-lər yazıldığı sıra ilə düzülmür. JVM əvvəl böyük primitive-ləri, sonra kiçikləri, ən sonda reference-ləri yerləşdirir. Hər field üçün ona sığan ən kiçik boşluğu seçir.

Hər field öz ölçüsünə bölünən offset-də başlayır: long 8-ə, int 4-ə bölünən yerdə. Object-in ölçüsü isə 8-ə bölünməlidir.

Öz class-ını qur və byte-ların necə yerləşdiyinə bax. Header-dən sonrakı 4 byte-ı çox vaxt bir int və ya reference doldurur.

Array-lər

Array-in header-i 16 byte-dır: mark word, class pointer və 4 byte length. Element-lər onun ardınca gəlir.

Primitive array dəyərləri özündə saxlayır. Integer[] isə yalnız reference saxlayır, hər Integer heap-də ayrıca 16 byte-lıq object-dir.

Ona görə 100 ədəd üçün int[] 416 byte tutur, Integer[] isə 2016 byte.

Collection-ların qiyməti

Collection-lar primitive saxlaya bilmir, hər ədəd Integer olur. Üstəlik hər element üçün daxili object-lər yaranır: HashMap-də Node, LinkedList-də ikiqat bağlı Node.

1000 ədəd int[]-də 4 KB, HashSet<Integer>-də isə 56 KB tutur, yəni 14 dəfə çox. Milyonlarla element olanda bu fərq vacibdir.

Primitive-lər üçün xüsusi collection-lar var, məsələn Eclipse Collections və fastutil kitabxanalarında. Onlar int[] kimi az yer tutur.

32 GB sərhədi

64-bit JVM-də pointer 8 byte-dır, amma heap kiçikdirsə JVM onu 4 byte-a sıxır: compressed oops.

4 byte-a 2³² fərqli dəyər sığır. JVM bunu 8-ə vurur, çünki object-lər 8-ə bölünən ünvanda başlayır. Nəticədə 32 GB-a qədər ünvan almaq olur.

Heap-i 31 GB-dan 32 GB-a qaldır və reference-lərin ölçüsünə bax. Java 25-də compact object headers də var: header 12 byte əvəzinə 8 byte tutur.