Ich weiß, dass Java-Sammlungen sehr speicherhungrig sind und haben selbst einen Test gemacht, was beweist, dass 4 GB kaum ausreichen, um einige Millionen Integer
s in HashSet
zu speichern.
Aber was, wenn ich "genug" Speicher habe? Was würde mit Collection.size()
geschehen?
BEARBEITEN: Gelöst: Collection.size()
gibt Integer.MAX
zurück, wenn der Integer-Bereich überschritten wird.
Neue Frage: wie die "echte" Anzahl von Elemente einer Sammlung dann?
ANMERKUNG 1: Entschuldigung, das ist wahrscheinlich eine Frage, die mich googeln lässt, aber ich habe wirklich nichts gefunden;)
ANMERKUNG 2: Soweit ich es verstehe, ist jeder ganzzahlige Eintrag einer Menge:
reference + cached_hashcode + boxed_integer_object + real_int_value
, richtig?
Hinweis 3: Lustig, sogar mit JDK7 und "komprimierten Zeigern", wenn die JVM 2 GB reellen Speicher verwendet, zeigt sie nur 1,5 GB zugewiesenen Speicher in VisualVM
.
Für diejenigen, die sich interessieren:
Getestet mit der x64-Version von JDK7 Build 105 unter OpenSuse 11.3 x64.
%Vor%Am Ende wurden ungefähr 2 GiB realer Speicher anstelle von 1,3 GiB verwendet, so dass der Verbrauch für jeden Eintrag noch größer als 53 Bytes ist.
Ihre Frage scheint einen ganz anderen Inhalt zu haben als der Titel.
Sie haben die Frage bereits im Titel beantwortet ( Integer.MAX_VALUE
wird zurückgegeben). Und nein: Es gibt keine Möglichkeit, die "wahre" Größe mit den normalen APIs herauszufinden, die für das Iterieren über die Sammlung und das Zählen sicher sind (mit long
natürlich).
Wenn Sie Set
von int
-Werten speichern möchten und Sie wissen, dass die Werte für den Bereich und sehr groß werden können, dann ist möglicherweise eine BitSet
eine bessere Implementierung :
Dies erzeugt eine Datenstruktur mit konstanter Größe, die alle Werte innerhalb des Bereichs enthalten kann, ohne die Größe zu ändern und eine relativ kleine Menge an Speicher zu belegen (1 Bit pro möglichem Wert plus etwas Overhead).
Diese Methode hat jedoch zwei Nachteile:
int
-Werte Set
API Beides kann leicht umschrieben werden, indem ein Wrapper geschrieben wird, der zwei BitSet
-Objekte (möglicherweise träge zugewiesen) verwendet, um den positiven bzw. negativen Wertebereich zu halten, und Adaptermethoden für die Set
-Schnittstelle implementiert.
Ich weiß, dass Java-Sammlungen sehr sind Gedächtnis-hungrig, und machte einen Test selbst, beweisen, dass 4GB gerade genug ist speichere ein paar Millionen von
Integers
in einemHashSet
.
Java Heap! = Systemspeicher. Die Standard-Heap-Größe von Java beträgt nur 128 MB. Beachten Sie, dass sich dies auch von dem Speicher unterscheidet, den die JVM verwendet.
In Bezug auf Ihre Frage: aus den Dokumenten,
Gibt die Anzahl der Elemente in diesem Feld zurück Sammlung. Wenn diese Sammlung enthält mehr als
Integer.MAX_VALUE
Elemente, gibtInteger.MAX_VALUE
zurück.
Die allgemeine Antwort für jede echte Prozessorarchitektur ist, dass Sie es einfach nicht können. Der Grund ist einfach: Es kann nicht mehr zugewiesene Objekte (von mindestens 1 Wortgröße) als adressierbaren Speicher geben.
Angesichts der virtuellen Natur der JVM gibt es natürlich ein Szenario, in dem das passieren kann.
int
ist immer 32bit signiert, und Sie können die JVM auf einer 64bit-Maschine implementieren und ausführen, auf der mehr als 2 GB Speicher adressiert werden können.
In diesem Fall sagt uns die Dokumentation, dass Integer.MAX_INT
zurückgegeben würde ... Und das ist ein großes Problem, weil jede Schleife, die eine Integer-Variable verwendet, die auf i < col.size()
stopt, für immer läuft (obwohl ich denke, dass alles, was 2**31-1
mal loop macht, würde lange genug dauern, um den Prozess sowieso beenden zu müssen.)
Tags und Links java memory integer collections overflow