Zajmowanie pamięci przez obiekty i ich metody w liście

0

Dzień dobry.
Takie pytanie .. zanim wyszukiwarki każą mi sprawdzać na piechotę jak to jest.

Mam w javie taką strukturę:

public static ArrayList<JRecord> JArrTRecord = new ArrayList<>();

gdzie JRecord to zwyczajna klasa z metodami typu copy, get, set, toString, toText i inne wg uznania, bez pod struktur dla uproszczenia.

I teraz pytanie: jak to jest aktualnie w javie z przydziałem pamieci dla Object i obiektów w takiej liście?
Czy jak mamy na liście 1000 firm to te metody copy, get, set, toString, toText są w jednej kopii a tylko dane są przechowywane razy 1000? czy każdy obiekt z listy to dane plus metody i wtedy w pamięci zajmuje dużo więcej miejsca cała taka lista?
Bo jeśli każdy obiekt ma swoją kopię, i do tego już dodamy kopie list zagnieżdżonych.. pytam z ciekawości i pod kontem optymalizacji też.
Pozdrawiam.

3

Czy jak mamy na liście 1000 firm to te metody copy, get, set, toString, toText są w jednej kopii a tylko dane są przechowywane razy 1000? czy każdy obiekt z listy to dane plus metody i wtedy w pamięci zajmuje dużo więcej miejsca cała taka lista?

jeśli chodzi o metody statyczne to te nie wymagają obiektu, więc nie są w żaden sposób duplikowane

jeśli chodzi o metody instancyjne (niestatyczne) to też nie są w żaden sposób duplikowane. każdy obiekt w nagłówku posiada wskaźnik do klasy (można się do niej dobrać odpalając obiekt.getClass()), a znając klasę znamy wszystkie metody i nie ma potrzeby ich duplikować w jakikolwiek sposób bezpośrednio w obiekcie.

inaczej mówiąc: rozmiar obiektu (a'ka instancji klasy) zależy od zbioru pól w tym obiekcie, a nie metod. osobne obiekty mają osobne obszary pamięci na swoje pola (których wartość może być niezależnie zmieniana), ale dwie instancje tej samej klasy mają dokładnie te same metody.

0
Integers napisał(a):

Dzień dobry.
Takie pytanie .. zanim wyszukiwarki każą mi sprawdzać na piechotę jak to jest.

Mam w javie taką strukturę:

public static ArrayList<JRecord> JArrTRecord = new ArrayList<>();

gdzie JRecord to zwyczajna klasa z metodami typu copy, get, set, toString, toText i inne wg uznania, bez pod struktur dla uproszczenia.

I teraz pytanie: jak to jest aktualnie w javie z przydziałem pamieci dla Object i obiektów w takiej liście?
Czy jak mamy na liście 1000 firm to te metody copy, get, set, toString, toText są w jednej kopii a tylko dane są przechowywane razy 1000? czy każdy obiekt z listy to dane plus metody i wtedy w pamięci zajmuje dużo więcej miejsca cała taka lista?
Bo jeśli każdy obiekt ma swoją kopię, i do tego już dodamy kopie list zagnieżdżonych.. pytam z ciekawości i pod kontem optymalizacji też.

To jest temat, który w Javie nie ma racji bytu specjalnie. W liście siedzi tylko referencja na obiekt, nikt więcej.

Jeśli chcesz coś optymalizować to uruchomi profiler i zobacz która operacja zżera najwięcej cpu i ramu.

1

W javie każdy obiekt (utworzony poprzez new) ma coś takiego jak object header https://stackoverflow.com/a/26416983/4638604 . Dalej referencje do wszystkich obiektów są trzymane jako wskaźniki (zwykły adres do obiektu). Mając taką klasę:

class A {
int a;
short b;
C c;
D D;
}

trzeba będzie mniej więcej zapłacić 8 bajtów na header, 4 dla pola typu int oraz 2x8 dla referencji czyli łącznie 28 bajtów (większość implementacji wyrównuje do wielokrotności 8, czyli w tym wypadku 32). Oczywiście instancje wskazywane przez c i d też swoje zajmują. Wszystko co napisałem to szczegóły implementacyjne: przykładowo same referencje często są optymalizowane by zajmować mniej (gdy maksymalna pamięć do zużycia jest dostatecznie mała). Czasami JIT potrafi rozłożyć obiekt na czynniki pierwsze i zostawić tylko co potrzebne np. jak tworzysz obiekt w metodzie, wywołujesz prostą metodę a potem nic się z nim nie dzieje.

Co do "kosztu" obsługi metod: praktycznie w każdym języku działą to tak, że albo nie trzeba tego trzymać (bo wiemy na etapie kompilacji jak np. w C) albo informacja jest zawarta w jednym miejscu. Tak jest w Javie, gdzie wszystkie metody mogą być poliformiczne: w tym wypadku ta informacja może być wyciągnięta z object header gdzie jest zapisany id klasy za pomocą którego można sprawdzić jakie to poliformiczne metody trzeba wywołać dla konkretnej instancji

0

Faktycznie było by to mało logiczne takie powielanie.. ale wolałem się upewnić.. Lepiej wiedzieć niż nie wiedzieć :].
Dziękuję wszystkim za wyczerpujące opisy. O takie sedno mi chodziło. Nie chciałem sprawdzać na piechotę..

W między czasie streszczenie tego co mi się w temacie udało znaleźć po drodze.

JAVA OBJECT LAYOUT – CZYLI JAK SPRAWDZIĆ ROZMIAR OBIEKTÓW W PAMIĘCI
https://javaleader.pl/2019/11/19/java-object-layout-czyli-jak-sprawdzic-rozmiar-obiektow-w-pamieci/

Sprawdzamy rozmiar naszych obiektów z Java Object Layout
https://codecouple.pl/2019/01/04/sprawdzamy-rozmiar-naszych-obiektow-z-java-object-layout/

https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/Instrumentation.html

Biblioteka ObjectSizeFetcher: https://stackoverflow.com/questions/20451589/get-the-size-of-object

Ale widzę, że Internet niby nie zapomina a część linków trafia pod 404. Nawet na GitHubie

1 użytkowników online, w tym zalogowanych: 0, gości: 1