Mam taką deklarację tablicy:
int a[];
Oto a
tablica int
typu pierwotnego . Gdzie jest przechowywana ta tablica? Czy jest przechowywany na stercie czy na stosie? Jest to typ int
pierwotny, wszystkie typy pierwotne nie są przechowywane na stercie.
Odpowiedzi:
Jak powiedział gurukulki, jest przechowywany na stercie. Jednak Twój post sugerował nieporozumienie, prawdopodobnie spowodowane przez jakąś osobę o dobrych intencjach, która propaguje mit, że „prymitywni zawsze żyją na stosie”. To nieprawda. Zmienne lokalne mają swoje wartości na stosie, ale nie wszystkie zmienne pierwotne są lokalne ...
Na przykład rozważ to:
public class Foo { int value; } ... public void someOtherMethod() { Foo f = new Foo(); ... }
Gdzie teraz
f.value
mieszka? Mit sugerowałby, że jest na stosie - ale w rzeczywistości jest częścią nowegoFoo
obiektu i żyje na stercie 1 . (Zauważ, że wartośćf
sama w sobie jest odniesieniem i żyje na stosie).Stamtąd łatwo jest przejść do tablic. Możesz myśleć o tablicy jako o dużej liczbie zmiennych - tak więc
new int[3]
jest trochę tak, jakbyś miał klasę w tej postaci:public class ArrayInt3 { public readonly int length = 3; public int value0; public int value1; public int value2; }
1 W rzeczywistości jest to bardziej skomplikowane niż to. Rozróżnienie między stosem a stertą polega głównie na szczegółach implementacji - uważam, że niektóre maszyny JVM, być może eksperymentalne, potrafią określić, kiedy obiekt nigdy nie „ucieka” z metody i mogą przydzielić cały obiekt na stosie. Jednak koncepcyjnie jest na kupie, jeśli zdecydujesz się na to.
źródło
String
jest wspierana przez rozszerzeniechar[]
. Uważam, że dosłowne ciągi znaków są przechowywane w publicznej stałej puli; w przypadku optymalizacji GC oznaczałoby to, że tablice zapasowe powinny być przechowywane w podobny sposób (w przeciwnym razie stałaby pula musiałaby być skanowana podczas dowolnego cyklu GC, gdzie w przeciwnym razie tablica podstawowa kwalifikowałaby się do gromadzenia).Będzie przechowywany na stercie
ponieważ tablica jest obiektem w java.
EDYCJA : jeśli masz
int [] testScores; testScores = new int[4];
Pomyśl o tym kodzie tak, jakby mówiło kompilatorowi: „Utwórz obiekt tablicy, który będzie zawierał cztery liczby całkowite, i przypisz go do zmiennej referencyjnej o nazwie
testScores
. Ponadto, ustaw każdyint
element na zero. Dzięki”.źródło
-g
opcję kompilatorowi. W przeciwnym razie zostanie zoptymalizowany.Jest to tablica typów pierwotnych, która sama w sobie nie jest prymitywna. Dobrą zasadą jest to, że gdy użyte jest nowe słowo kluczowe, wynik będzie na stercie.
źródło
Chciałem tylko podzielić się kilkoma testami, które przeprowadziłem na ten temat.
Tablica o rozmiarze 10 milionów
public static void main(String[] args) { memInfo(); double a[] = new double[10000000]; memInfo(); }
Wynik:
------------------------ max mem = 130.0 MB total mem = 85.0 MB free mem = 83.6 MB used mem = 1.4 MB ------------------------ ------------------------ max mem = 130.0 MB total mem = 130.0 MB free mem = 48.9 MB used mem = 81.1 MB ------------------------
Jak widać, używany rozmiar stosu został zwiększony o ~ 80 MB, co daje 10m * sizeof (double).
Ale jeśli użyjemy Double zamiast double
public static void main(String[] args) { memInfo(); Double a[] = new Double[10000000]; memInfo(); }
Wyjście pokaże 40 MB. Mamy tylko podwójne referencje, nie są one zainicjalizowane.
Wypełnianie go Double
public static void main(String[] args) { memInfo(); Double a[] = new Double[10000000]; Double qq = 3.1d; for (int i = 0; i < a.length; i++) { a[i] = qq; } memInfo(); }
Nadal 40 MB. Ponieważ wszystkie wskazują na ten sam obiekt Double.
Zamiast tego inicjalizuję double
public static void main(String[] args) { memInfo(); Double a[] = new Double[10000000]; Double qq = 3.1d; for (int i = 0; i < a.length; i++) { a[i] = qq.doubleValue(); } memInfo(); } Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Linia
jest równa
co jest równoważne
a[i] = new Double(qq.doubleValue());
Ponieważ za każdym razem tworzymy nowe podwójne obiekty, wysadzamy stos. To pokazuje, że wartości wewnątrz klasy Double są przechowywane w stercie.
źródło
W języku programowania Java tablice są obiektami, są tworzone dynamicznie i mogą być przypisane do zmiennych typu Object.
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html
źródło