Nein. In der Standard-Java SE-Klassenbibliothek gibt es keine solche Methode.
Nach Ansicht der Designer wird es in Java nicht benötigt, da die Sprache die Notwendigkeit beseitigt, dass eine Anwendung 1 weiß, wie viel Speicherplatz für einen primitiven Wert, ein Objekt oder ein Array mit einer bestimmten Anzahl von Elementen reserviert werden muss.
Sie könnten denken, dass ein Operator sizeof für Personen nützlich wäre, die wissen müssen, wie viel Speicherplatz ihre Datenstrukturen beanspruchen. Sie können diese und weitere Informationen jedoch auch einfach und zuverlässig mit einem Java-Speicherprofiler abrufen, sodass keine sizeof-Methode erforderlich ist.
Frühere Kommentatoren machten den Punkt, sizeof(someType)der lesbarer wäre als 4. Wenn Sie dieses Argument der Lesbarkeit akzeptieren, liegt das Mittel in Ihren Händen. Definieren Sie einfach eine Klasse wie diese ...
Oder definieren Sie einige benannte Konstanten. z.B
publicstaticfinalint SIZE_OF_INT = 4;
Oder (Java 8 und höher) verwenden Sie die Integer.BYTESKonstante und so weiter.
Warum haben die Java-Designer dies nicht in Standardbibliotheken implementiert? Meine Vermutung ist, dass:
sie glauben nicht, dass es notwendig ist,
sie glauben nicht, dass es eine ausreichende Nachfrage dafür gibt, und
Sie denken nicht, dass es die Mühe wert ist.
Es gibt auch das Problem, dass die nächste Nachfrage nach einer sizeof(Object o)Methode wäre, die mit technischen Schwierigkeiten behaftet ist.
Das Schlüsselwort oben ist "sie"!
1 - Ein Programmierer muss möglicherweise wissen, um platzsparende Datenstrukturen zu entwerfen. Ich kann mir jedoch nicht vorstellen, warum diese Informationen zur Laufzeit über einen Methodenaufruf im Anwendungscode benötigt werden.
Eine oberflächliche Antwort ist, dass Java nichts wie Cs sizeof () liefert. Lassen Sie uns jedoch überlegen, warum ein Java-Programmierer dies gelegentlich möchte.
Der AC-Programmierer verwaltet die meisten Speicherzuordnungen für die Datenstruktur selbst, und sizeof () ist für die Kenntnis der zuzuweisenden Speicherblockgrößen unverzichtbar. Darüber hinaus tun C-Speicherzuordnungen wie malloc () bei der Objektinitialisierung fast nichts: Ein Programmierer muss alle Objektfelder festlegen, die Zeiger auf weitere Objekte sind. Aber wenn alles gesagt und codiert ist, ist die C / C ++ - Speicherzuweisung ziemlich effizient.
Im Vergleich dazu sind Java-Objektzuweisung und -Konstruktion miteinander verbunden (es ist unmöglich, eine zugewiesene, aber nicht initialisierte Objektinstanz zu verwenden). Wenn eine Java-Klasse Felder definiert, die auf weitere Objekte verweisen, werden diese häufig auch zur Erstellungszeit festgelegt. Durch das Zuweisen eines Java-Objekts werden daher häufig zahlreiche miteinander verbundene Objektinstanzen zugewiesen: ein Objektdiagramm. In Verbindung mit der automatischen Speicherbereinigung ist dies allzu praktisch und kann dazu führen, dass Sie sich nie um Details zur Java-Speicherzuweisung kümmern müssen.
Dies funktioniert natürlich nur für einfache Java-Anwendungen. Im Vergleich zu C / C ++ belegen äquivalente Java-Datenstrukturen tendenziell mehr physischen Speicher. In der Entwicklung von Unternehmenssoftware ist die Annäherung an den maximal verfügbaren virtuellen Speicher der heutigen 32-Bit-JVMs eine häufige Einschränkung der Skalierbarkeit. Ein Java-Programmierer könnte daher von sizeof () oder ähnlichem profitieren, um zu beobachten, ob seine Datenstrukturen zu groß werden oder Speicherengpässe enthalten. Glücklicherweise können Sie mit Java Reflection ein solches Tool ganz einfach schreiben.
Bevor ich fortfahre, werde ich auf einige häufige, aber falsche Antworten auf die Frage dieses Artikels verzichten. Irrtum: Sizeof () wird nicht benötigt, da die Größen der Java-Basistypen festgelegt sind
Ja, ein Java-Int ist 32 Bit in allen JVMs und auf allen Plattformen, aber dies ist nur eine Sprachspezifikationsanforderung für die vom Programmierer wahrnehmbare Breite dieses Datentyps. Ein solches int ist im Wesentlichen ein abstrakter Datentyp und kann beispielsweise durch ein physisches 64-Bit-Speicherwort auf einer 64-Bit-Maschine gesichert werden. Gleiches gilt für nicht primitive Typen: Die Java-Sprachspezifikation sagt nichts darüber aus, wie Klassenfelder im physischen Speicher ausgerichtet werden sollen oder dass ein Array von Booleschen Werten nicht als kompakter Bitvektor in der JVM implementiert werden kann. Irrtum: Sie können die Größe eines Objekts messen, indem Sie es in einen Byte-Stream serialisieren und die resultierende Stream-Länge anzeigen
Der Grund, warum dies nicht funktioniert, ist, dass das Serialisierungslayout nur eine Fernreflexion des tatsächlichen In-Memory-Layouts ist. Eine einfache Möglichkeit, dies zu erkennen, besteht darin, zu untersuchen, wie Strings serialisiert werden: Im Speicher beträgt jedes Zeichen mindestens 2 Byte, in serialisierter Form sind Strings jedoch UTF-8-codiert, sodass jeder ASCII-Inhalt halb so viel Speicherplatz beansprucht
"Glücklicherweise können Sie mit Java Reflection ein solches Tool ganz einfach schreiben." Wie?
dfrankow
Ich habe mich immer gefragt, wie groß eine Referenz ist und was darin enthalten ist.
Marichyasana
11
Die Java Native Access- Bibliothek wird normalerweise zum Aufrufen nativer gemeinsam genutzter Bibliotheken aus Java verwendet. Innerhalb dieser Bibliothek gibt es Methoden zum Bestimmen der Größe von Java-Objekten:
Die getNativeSize(Class cls)Methode und ihre Überladungen geben die Größe für die meisten Klassen an.
Wenn Ihre Klassen von der Strukturklasse von JNA erben, ist die calculateSize(boolean force)Methode alternativ verfügbar.
Vielen Dank für diese Antwort! Ich habe versucht, JNA zu verwenden, wo ein Argument mit Cs sizeof () abgeleitet wird, und genau das habe ich gebraucht!
Daniel Widdis
@sprocketonline - die Links sind defekt, könnten Sie sie bitte aktualisieren
Naman
10
Sie können Bitmanipulationen wie unten ausführen, um die Größe der Grundelemente zu erhalten:
publicintsizeofInt(){
int i = 1, j = 0;
while (i != 0) {
i = (i<<1); j++;
}
return j;
}
publicintsizeofChar(){
char i = 1, j = 0;
while (i != 0) {
i = (char) (i<<1); j++;
}
return j;
}
sizeof (in C) gibt die Anzahl der Bytes zurück, während diese Routinen die Anzahl der Bits zurückgeben würden.
LarsH
5
Wenn Sie i<<8stattdessen verwenden, wird die Anzahl der Bytes angegeben.
Richard Sun
Ja, Sie können die Bytes / Bits so berechnen, aber das ist nicht erforderlich. Die Java-Sprachspezifikation garantiert, dass sich die Anzahl der Bytes, die zur Darstellung jedes primitiven Typs benötigt werden, niemals ändern wird.
Stephen C
9
Wie hier erwähnt , gibt es Möglichkeiten, die Größe primitiver Typen durch ihre Wrapper zu ermitteln.
zB für a longkönnte dies Long.SIZE / Byte.SIZEvon Java 1.5 (wie bereits von zeodtr erwähnt ) oder Long.BYTESvon Java 8 sein
Die Instrumentation-Klasse verfügt über eine getObjectSize () -Methode. Sie sollten sie jedoch nicht zur Laufzeit verwenden müssen. Der einfachste Weg, die Speichernutzung zu untersuchen, ist die Verwendung eines Profilers, mit dem Sie die Speichernutzung verfolgen können.
EhCache bietet eine SizeOf- Klasse, die versucht, den Instrumentation- Agenten zu verwenden, und auf einen anderen Ansatz zurückgreift, wenn der Agent nicht geladen ist oder nicht geladen werden kann ( Details hier ).
Es gibt eine implementierungsspezifische Annäherung an die vom angegebenen Objekt verbrauchte Speichermenge zurück. Das Ergebnis kann einen Teil oder den gesamten Overhead des Objekts enthalten und ist daher für den Vergleich innerhalb einer Implementierung nützlich, jedoch nicht zwischen Implementierungen. Die Schätzung kann sich während eines einzelnen Aufrufs der JVM ändern.
Auf SourceForge.net ist eine Klasse / JAR verfügbar, die Java-Instrumente verwendet, um die Größe eines Objekts zu berechnen. Hier ist ein Link zur Beschreibung: java.sizeOf
publicclassPrimitiveTypesV2{
publicstaticvoidmain(String[] args){
Class typesList[] = {
Boolean.class , Byte.class, Character.class, Short.class, Integer.class,
Long.class, Float.class, Double.class, Boolean.TYPE, Byte.TYPE, Character.TYPE,
Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE
};
try {
for ( Class type : typesList ) {
if (type.isPrimitive()) {
System.out.println("Primitive type:\t" + type);
}
else {
boolean hasSize = false;
java.lang.reflect.Field fields[] = type.getFields();
for (int count=0; count<fields.length; count++) {
if (fields[count].getName().contains("SIZE")) hasSize = true;
}
if (hasSize) {
System.out.println("Bits size of type " + type + " :\t\t\t" + type.getField("SIZE").getInt(type) );
double value = type.getField("MIN_VALUE").getDouble(type);
long longVal = Math.round(value);
if ( (value - longVal) == 0) {
System.out.println("Min value for type " + type + " :\t\t" + longVal );
longVal = Math.round(type.getField("MAX_VALUE").getDouble(type));
System.out.println("Max value for type " + type + " :\t\t" + longVal );
}
else {
System.out.println("Min value for type " + type + " :\t\t" + value );
value = type.getField("MAX_VALUE").getDouble(type);
System.out.println("Max value for type " + type + " :\t\t" + value );
}
}
else {
System.out.println(type + "\t\t\t type without SIZE field.");
}
} // if not primitive
} // for typesList
} catch (Exception e) {e.printStackTrace();}
} // main
} // class PrimitiveTypes
Ich glaube nicht, dass es in der Java-API ist. Die meisten Datentypen, die eine Reihe von Elementen enthalten, verfügen jedoch über eine size()Methode. Ich denke, Sie können leicht eine Funktion schreiben, um die Größe selbst zu überprüfen?
Antworten:
Nein. In der Standard-Java SE-Klassenbibliothek gibt es keine solche Methode.
Nach Ansicht der Designer wird es in Java nicht benötigt, da die Sprache die Notwendigkeit beseitigt, dass eine Anwendung 1 weiß, wie viel Speicherplatz für einen primitiven Wert, ein Objekt oder ein Array mit einer bestimmten Anzahl von Elementen reserviert werden muss.
Sie könnten denken, dass ein Operator sizeof für Personen nützlich wäre, die wissen müssen, wie viel Speicherplatz ihre Datenstrukturen beanspruchen. Sie können diese und weitere Informationen jedoch auch einfach und zuverlässig mit einem Java-Speicherprofiler abrufen, sodass keine sizeof-Methode erforderlich ist.
Frühere Kommentatoren machten den Punkt,
sizeof(someType)
der lesbarer wäre als4
. Wenn Sie dieses Argument der Lesbarkeit akzeptieren, liegt das Mittel in Ihren Händen. Definieren Sie einfach eine Klasse wie diese ...public class PrimitiveSizes { public static int sizeof(byte b) { return 1; } public static int sizeof(short s) { return 2; } // etcetera }
... und statisch importieren ...
import static PrimitiveSizes.*;
Oder definieren Sie einige benannte Konstanten. z.B
public static final int SIZE_OF_INT = 4;
Oder (Java 8 und höher) verwenden Sie die
Integer.BYTES
Konstante und so weiter.Warum haben die Java-Designer dies nicht in Standardbibliotheken implementiert? Meine Vermutung ist, dass:
Es gibt auch das Problem, dass die nächste Nachfrage nach einer
sizeof(Object o)
Methode wäre, die mit technischen Schwierigkeiten behaftet ist.Das Schlüsselwort oben ist "sie"!
1 - Ein Programmierer muss möglicherweise wissen, um platzsparende Datenstrukturen zu entwerfen. Ich kann mir jedoch nicht vorstellen, warum diese Informationen zur Laufzeit über einen Methodenaufruf im Anwendungscode benötigt werden.
quelle
Aus dem Artikel in JavaWorld
quelle
Die Java Native Access- Bibliothek wird normalerweise zum Aufrufen nativer gemeinsam genutzter Bibliotheken aus Java verwendet. Innerhalb dieser Bibliothek gibt es Methoden zum Bestimmen der Größe von Java-Objekten:
Die
getNativeSize(Class cls)
Methode und ihre Überladungen geben die Größe für die meisten Klassen an.Wenn Ihre Klassen von der Strukturklasse von JNA erben, ist die
calculateSize(boolean force)
Methode alternativ verfügbar.quelle
Sie können Bitmanipulationen wie unten ausführen, um die Größe der Grundelemente zu erhalten:
public int sizeofInt() { int i = 1, j = 0; while (i != 0) { i = (i<<1); j++; } return j; } public int sizeofChar() { char i = 1, j = 0; while (i != 0) { i = (char) (i<<1); j++; } return j; }
quelle
i<<8
stattdessen verwenden, wird die Anzahl der Bytes angegeben.Wie hier erwähnt , gibt es Möglichkeiten, die Größe primitiver Typen durch ihre Wrapper zu ermitteln.
zB für a
long
könnte diesLong.SIZE / Byte.SIZE
von Java 1.5 (wie bereits von zeodtr erwähnt ) oderLong.BYTES
von Java 8 seinquelle
Es gibt einen zeitgemäßen Weg, dies für Primitive zu tun. Verwendung
BYTES
von Typen.System.out.println("byte " + Byte.BYTES); System.out.println("char " + Character.BYTES); System.out.println("int " + Integer.BYTES); System.out.println("long " + Long.BYTES); System.out.println("short " + Short.BYTES); System.out.println("double " + Double.BYTES); System.out.println("float " + Float.BYTES);
Es fuehrt zu,
byte 1 char 2 int 4 long 8 short 2 double 8 float 4
quelle
Sie können Integer.SIZE / 8, Double.SIZE / 8 usw. für primitive Typen aus Java 1.5 verwenden.
quelle
Die Instrumentation-Klasse verfügt über eine getObjectSize () -Methode. Sie sollten sie jedoch nicht zur Laufzeit verwenden müssen. Der einfachste Weg, die Speichernutzung zu untersuchen, ist die Verwendung eines Profilers, mit dem Sie die Speichernutzung verfolgen können.
quelle
EhCache bietet eine SizeOf- Klasse, die versucht, den Instrumentation- Agenten zu verwenden, und auf einen anderen Ansatz zurückgreift, wenn der Agent nicht geladen ist oder nicht geladen werden kann ( Details hier ).
Siehe auch den Agenten von Heinz Kabutz .
quelle
Ich habe beschlossen, eine Aufzählung zu erstellen, ohne die Standard-Java-Konventionen zu befolgen. Vielleicht gefällt dir das.
public enum sizeof { ; public static final int FLOAT = Float.SIZE / 8; public static final int INTEGER = Integer.SIZE / 8; public static final int DOUBLE = Double.SIZE / 8; }
quelle
Versuchen Sie es mit java.lang.Instrumentation.getObjectSize (Object) . Aber bitte beachten Sie das
quelle
Auf SourceForge.net ist eine Klasse / JAR verfügbar, die Java-Instrumente verwendet, um die Größe eines Objekts zu berechnen. Hier ist ein Link zur Beschreibung: java.sizeOf
quelle
Nur ein paar Tests darüber:
public class PrimitiveTypesV2 { public static void main (String[] args) { Class typesList[] = { Boolean.class , Byte.class, Character.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE }; try { for ( Class type : typesList ) { if (type.isPrimitive()) { System.out.println("Primitive type:\t" + type); } else { boolean hasSize = false; java.lang.reflect.Field fields[] = type.getFields(); for (int count=0; count<fields.length; count++) { if (fields[count].getName().contains("SIZE")) hasSize = true; } if (hasSize) { System.out.println("Bits size of type " + type + " :\t\t\t" + type.getField("SIZE").getInt(type) ); double value = type.getField("MIN_VALUE").getDouble(type); long longVal = Math.round(value); if ( (value - longVal) == 0) { System.out.println("Min value for type " + type + " :\t\t" + longVal ); longVal = Math.round(type.getField("MAX_VALUE").getDouble(type)); System.out.println("Max value for type " + type + " :\t\t" + longVal ); } else { System.out.println("Min value for type " + type + " :\t\t" + value ); value = type.getField("MAX_VALUE").getDouble(type); System.out.println("Max value for type " + type + " :\t\t" + value ); } } else { System.out.println(type + "\t\t\t type without SIZE field."); } } // if not primitive } // for typesList } catch (Exception e) {e.printStackTrace();} } // main } // class PrimitiveTypes
quelle
Ich glaube nicht, dass es in der Java-API ist. Die meisten Datentypen, die eine Reihe von Elementen enthalten, verfügen jedoch über eine
size()
Methode. Ich denke, Sie können leicht eine Funktion schreiben, um die Größe selbst zu überprüfen?quelle
ja..in JAVA
System.out.println(Integer.SIZE/8); //gives you 4. System.out.println(Integer.SIZE); //gives you 32. //Similary for Byte,Long,Double....
quelle