Usuwanie śmieci liter ciągów
Czytam o Garbage collection i dostaję mylące wyniki wyszukiwania, Gdy Szukam ciągów literalnych garbage collections.
Potrzebuję wyjaśnienia następujących kwestii:
Jeśli łańcuch znaków jest zdefiniowany jako literalny podczas kompilacji [np:
String str = "java"
], to czy zostanie pobrany?Jeśli użyjesz metody intern [np.:
String str = new String("java").intern()
], to czy będzie ona zbierana? Również będzie traktowany inaczej niż literał Łańcuchowy w punkcie 1.W niektórych miejscach mówi się, że literały będą śmieciami zbieranymi tylko wtedy, gdy klasa
String
zostanie rozładowana? Czy to ma sens, bo nie sądzę, że Klasa kiedykolwiek zostanie rozładowana.
4 answers
Prawdopodobnie nie. Obiekty code będą zawierać jedno lub więcej odniesień do obiektówJeśli łańcuch jest zdefiniowany jako literalny w czasie kompilacji [np:
String str = "java";
], to czy zostanie pobrany?
String
, które reprezentują literały. Tak długo, jak obiekty kodu są osiągalne, obiekty String
będą do.
Możliwe jest, że obiekty kodu stają się nieosiągalne, ale tylko wtedy, gdy zostały załadowane dynamicznie ... a ich Klasa zostaje zniszczona.
Jeśli użyję metody intern[np:
String str = new String("java").intern()
] to czy będzie to śmieci zbierane?
Obiekt zwrócony przez wywołanie intern
będzie tym samym obiektem, który reprezentuje literał "java"
. (Literał "java"
jest internowany w czasie ładowania klasy. Po internowaniu nowo zbudowanego obiektu String
w urywku kodu, obiekt wyszukuje i zwraca wcześniej internowany łańcuch "java"
.)
Jednak internowane ciągi, które nie są identyczne z literałami ciągów Mogą być zbierane śmieci, gdy staną się nieosiągalne. Przestrzeń PermGen to śmieci zebrane na wszystkich ostatnich hotspotach JVM. (Przed Java 8 ... który całkowicie spada PermGen.)
Również będzie traktowany inaczej niż literał Łańcuchowy w punkcie 1.
Nie ... ponieważ jest to ten sam obiekt co literalny łańcuch znaków.
I rzeczywiście, kiedy zrozumiesz, co się dzieje, jest jasne, że literały ciągów nie są traktowane specjalnie ani jedno, ani drugie. Jest to tylko zastosowanie zasady "osiągalności"...
Masz rację. To nie ma sensu. Źródła, które tak twierdziły, są błędne. (Byłoby pomocne, gdybyś opublikował adres URL, abyśmy mogli przeczytać, co mówią sami ...)W niektórych miejscach mówi się, że literały będą śmieciami zbieranymi tylko wtedy, gdy
String
klasa zostanie rozładowana? Czy to ma sens, bo nie sądzę, żeby Klasa kiedykolwiek została rozładowana.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 07:38:36
W normalnych okolicznościach literały łańcuchowe i klasy są przydzielane do stałej generacji JVM ("Permen") i zwykle nigdy nie będą gromadzone. Ciągi, które są internowane (np. mystring.intern()
) są przechowywane w puli pamięci należącej do klasy String
w permgen i kiedyś zdarzało się, że agresywne internowanie mogło spowodować wyciek przestrzeni, ponieważ sama pula łańcuchów zawierała odniesienie do każdego łańcucha, nawet jeśli nie istniały żadne inne odniesienia. Widocznie nie jest to już prawdą, przynajmniej od JDK 1.6 (patrz np. TUTAJ).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 16:43:47
- literalny ciąg znaków pozostanie w pamięci tak długo, jak długo program jest w pamięci.
-
str
będą zbierane śmieci, ale literal, z którego jest tworzony, nie będzie. - to ma sens, ponieważ Klasa string jest rozładowywana, gdy program jest rozładowywany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 15:58:54
intern()
metoda sprawdza dostępność obiektu w Puli łańcuchów. Jeżeli obiekt / literal jest dostępny, wtedy zostanie zwrócone odniesienie do niego. Jeśli literał nie znajduje się w Puli, wtedy obiekt zostanie załadowany w obszarze perm (String pool) i wtedy zostanie zwrócone odniesienie do niego. Musimy używać metody intern()
rozsądnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 16:05:53