Java 中是否有类似 sizeof 的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2370288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there any sizeof-like method in Java?
提问by Ankit Sachan
Is there any built-in method in Java to find the size of any datatype? Is there any way to find size?
Java 中是否有任何内置方法来查找任何数据类型的大小?有什么办法可以找到大小吗?
采纳答案by Stephen C
No. There is no such method in the standard Java SE class library.
不。标准Java SE 类库中没有这样的方法。
The designers' view is that it is not needed in Java, since the language removes the need for an application1to know about how much space needs to be reserved for a primitive value, an object or an array with a given number of elements.
设计者的观点是在 Java 中不需要它,因为该语言不需要应用程序1知道需要为原始值、对象或具有给定数量元素的数组保留多少空间。
You might think that a sizeof operator would be useful for people that need to know how much space their data structures take. However you can also get this information and more, simply and reliably using a Java memory profiler, so there is no need for a sizeof method.
您可能认为 sizeof 运算符对于需要知道其数据结构占用多少空间的人很有用。但是,您也可以使用 Java 内存分析器简单可靠地获取此信息以及更多信息,因此不需要 sizeof 方法。
Previous commenters made the point that sizeof(someType)
would be more readable than 4
. If you accept that readability argument, then the remedy is in your hands. Simply define a class like this ...
以前的评论者提出的观点sizeof(someType)
比4
. 如果您接受该可读性论点,那么补救措施就在您手中。简单地定义一个这样的类......
public class PrimitiveSizes {
public static int sizeof(byte b) { return 1; }
public static int sizeof(short s) { return 2; }
// etcetera
}
... and statically import it ...
...并静态导入它...
import static PrimitiveSizes.*;
Or define some named constants; e.g.
或者定义一些命名常量;例如
public static final int SIZE_OF_INT = 4;
Or (Java 8 and later) use the Integer.BYTES
constant, and so on.
或者(Java 8 及更高版本)使用Integer.BYTES
常量,依此类推。
Why haven't the Java designers implemented this in standard libraries? My guess is that:
为什么 Java 设计者没有在标准库中实现它?我的猜测是:
- they don't think there is a need for it,
- they don't think there is sufficient demand for it, and
- they don't think it is worth the effort.
- 他们认为没有必要,
- 他们认为没有足够的需求,并且
- 他们认为不值得付出努力。
There is also the issue that the next demand would be for a sizeof(Object o)
method, which is fraught with technical difficulties.
还有一个问题是,下一个需求将是一种sizeof(Object o)
充满技术困难的方法。
The key word in the above is "they"!
上面的关键词是“他们”!
It does not matter what you or I think about it. And by extension, debating this topic in the comments is moot. Please, just, don't.
你或我怎么想都无所谓。此外,在评论中讨论这个话题是没有实际意义的。请,只是,不要。
1 - A programmer may need to know in order to design space efficient data structures. However, I can't imagine why that information would be needed in application code at runtime via a method call.
1 - 程序员可能需要了解以设计节省空间的数据结构。但是,我无法想象为什么在运行时通过方法调用在应用程序代码中需要这些信息。
回答by Alfred
I don't think it is in the java API. but most datatypes which have a number of elements in it, have a size()
method. I think you can easily write a function to check for size yourself?
我不认为它在 java API 中。但是大多数包含许多元素的数据类型都有一个size()
方法。我认为您可以轻松编写一个函数来自己检查大小?
回答by Ramesh
From the article in JavaWorld
A superficial answer is that Java does not provide anything like C's sizeof(). However, let's consider why a Java programmer might occasionally want it.
A C programmer manages most datastructure memory allocations himself, and sizeof() is indispensable for knowing memory block sizes to allocate. Additionally, C memory allocators like malloc() do almost nothing as far as object initialization is concerned: a programmer must set all object fields that are pointers to further objects. But when all is said and coded, C/C++ memory allocation is quite efficient.
By comparison, Java object allocation and construction are tied together (it is impossible to use an allocated but uninitialized object instance). If a Java class defines fields that are references to further objects, it is also common to set them at construction time. Allocating a Java object therefore frequently allocates numerous interconnected object instances: an object graph. Coupled with automatic garbage collection, this is all too convenient and can make you feel like you never have to worry about Java memory allocation details.
Of course, this works only for simple Java applications. Compared with C/C++, equivalent Java datastructures tend to occupy more physical memory. In enterprise software development, getting close to the maximum available virtual memory on today's 32-bit JVMs is a common scalability constraint. Thus, a Java programmer could benefit from sizeof() or something similar to keep an eye on whether his datastructures are getting too large or contain memory bottlenecks. Fortunately, Java reflection allows you to write such a tool quite easily.
Before proceeding, I will dispense with some frequent but incorrect answers to this article's question. Fallacy: Sizeof() is not needed because Java basic types' sizes are fixed
Yes, a Java int is 32 bits in all JVMs and on all platforms, but this is only a language specification requirement for the programmer-perceivable width of this data type. Such an int is essentially an abstract data type and can be backed up by, say, a 64-bit physical memory word on a 64-bit machine. The same goes for nonprimitive types: the Java language specification says nothing about how class fields should be aligned in physical memory or that an array of booleans couldn't be implemented as a compact bitvector inside the JVM. Fallacy: You can measure an object's size by serializing it into a byte stream and looking at the resulting stream length
The reason this does not work is because the serialization layout is only a remote reflection of the true in-memory layout. One easy way to see it is by looking at how Strings get serialized: in memory every char is at least 2 bytes, but in serialized form Strings are UTF-8 encoded and so any ASCII content takes half as much space
一个肤浅的回答是,Java 没有提供像 C 的 sizeof() 这样的任何东西。但是,让我们考虑一下为什么 Java 程序员可能偶尔会想要它。
AC 程序员自己管理大多数数据结构内存分配,而 sizeof() 对于了解要分配的内存块大小是必不可少的。此外,就对象初始化而言,像 malloc() 这样的 C 内存分配器几乎什么都不做:程序员必须设置所有对象字段,这些对象字段是指向更多对象的指针。但总而言之,C/C++ 内存分配是相当有效的。
相比之下,Java 对象分配和构造是捆绑在一起的(不可能使用已分配但未初始化的对象实例)。如果 Java 类定义了引用其他对象的字段,则在构造时设置它们也是很常见的。因此,分配 Java 对象经常会分配大量互连的对象实例:对象图。再加上自动垃圾收集,这实在是太方便了,让您感觉永远不必担心 Java 内存分配细节。
当然,这仅适用于简单的 Java 应用程序。与 C/C++ 相比,等效的 Java 数据结构往往会占用更多的物理内存。在企业软件开发中,接近当今 32 位 JVM 上的最大可用虚拟内存是一个常见的可扩展性约束。因此,Java 程序员可以从 sizeof() 或类似的东西中受益,以密切关注他的数据结构是否变得太大或包含内存瓶颈。幸运的是,Java 反射使您可以很容易地编写这样的工具。
在继续之前,我将省略对本文问题的一些常见但不正确的答案。谬误:不需要 Sizeof() 因为 Java 基本类型的大小是固定的
是的,Java int 在所有 JVM 和所有平台上都是 32 位,但这只是程序员可感知的这种数据类型宽度的语言规范要求。这样的 int 本质上是一种抽象数据类型,可以由 64 位机器上的 64 位物理内存字备份。非原始类型也是如此:Java 语言规范没有说明类字段应该如何在物理内存中对齐,或者布尔数组不能在 JVM 中实现为紧凑的位向量。谬误:您可以通过将对象序列化为字节流并查看生成的流长度来测量对象的大小
这不起作用的原因是因为序列化布局只是真实内存中布局的远程反映。查看它的一种简单方法是查看字符串如何序列化:在内存中,每个字符至少为 2 个字节,但在序列化形式中,字符串是 UTF-8 编码的,因此任何 ASCII 内容都占用一半的空间
回答by Iain Sproat
The Java Native Accesslibrary is typically used for calling native shared libraries from Java. Within this library there exist methods for determining the size of Java objects:
该Java本机访问库通常用于从Java调用本地共享库。在这个库中有确定 Java 对象大小的方法:
The getNativeSize(Class cls)
method and its overloads will provide the size for most classes.
该getNativeSize(Class cls)
方法及其重载将为大多数类提供大小。
Alternatively, if your classes inherit from JNA's Structure class the calculateSize(boolean force)
method will be available.
或者,如果您的类继承自 JNA 的 Structure 类,则该calculateSize(boolean force)
方法将可用。
回答by Peter Lawrey
The Instrumentation class has a getObjectSize() method however, you shouldn't need to use it at runtime. The easiest way to examine memory usage is to use a profiler which is designed to help you track memory usage.
Instrumentation 类有一个 getObjectSize() 方法,但是您不需要在运行时使用它。检查内存使用情况的最简单方法是使用旨在帮助您跟踪内存使用情况的分析器。
回答by sourcedelica
EhCache provides a SizeOfclass that will try to use the Instrumentationagent and will fall back to a different approach if the agent is not loaded or cannot be loaded (details here).
EhCache 提供了一个SizeOf类,该类将尝试使用Instrumentation代理,如果未加载或无法加载代理,它将回退到不同的方法(详情请点击此处)。
Also see the agent from Heinz Kabutz.
另请参阅Heinz Kabutz 的经纪人。
回答by Murali Mohan
You can do bit manipulations like below to obtain the size of primitives:
您可以进行如下位操作以获得基元的大小:
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;
}
回答by Andy King
There's a class/jar available on SourceForge.net that uses Java instrumentation to calculate the size of any object. Here's a link to the description: java.sizeOf
SourceForge.net 上有一个类/jar,它使用 Java 检测来计算任何对象的大小。这是描述的链接:java.sizeOf
回答by zeodtr
You can use Integer.SIZE / 8, Double.SIZE / 8, etc. for primitive types from Java 1.5.
对于 Java 1.5 中的原始类型,您可以使用 Integer.SIZE / 8、Double.SIZE / 8 等。
回答by Mr Tsjolder
As mentioned here, there are possibilities to get the size of primitive types through their wrappers.
正如这里提到的,有可能通过它们的包装器获得原始类型的大小。
e.g. for a long
this could be Long.SIZE / Byte.SIZE
from java 1.5 (as mentioned by zeodtralready) or Long.BYTES
as from java 8
例如,对于 along
这可能Long.SIZE / Byte.SIZE
来自 java 1.5(正如zeodtr已经提到的)或Long.BYTES
来自 java 8