Java减少了对象的大小

Java减少了对象的大小,java,char,boolean,Java,Char,Boolean,我正在创建一个trie,我的应用程序将保存在它的内存中。Trie将有很多节点,我正在考虑如何减少空间使用。 当然,我会使用trie-to-DAWG算法来减少节点数量,但据我所知,这还不够 这是一个节点类 class Node{ char letter; boolean EOW; // end of word Node child; // first child Node next; // next Node on this level } 据我所知,这个类的对象将有14个字节(

我正在创建一个trie,我的应用程序将保存在它的内存中。Trie将有很多节点,我正在考虑如何减少空间使用。 当然,我会使用trie-to-DAWG算法来减少节点数量,但据我所知,这还不够

这是一个节点类

class Node{
  char letter;
  boolean EOW; // end of word
  Node child; // first child
  Node next; // next Node on this level
}
据我所知,这个类的对象将有14个字节(2个字节用于char,4个字节用于boolean变量,2*4将保留用于引用)

我想我可以用字节替换字符。这将节省1字节。然而,我不知道这将需要多少时间在类型铸造。很可能这是一个糟糕的设计

布尔值需要4个字节,也许你知道我可以用什么来代替布尔值


所以我需要你们帮我减小节点的大小。提前感谢。

如果
字母
只需要5位,而
eow
只需要一位,您可以将它们打包到一个
字节
中以节省内存

char letter = ...;
boolean eow = ...;

byte packed = (byte) ((eow ? 0b10_0000 : 0) | letter);

letter = (char) (packed & 0b1_1111);
eow = (packed & 0b10_0000) != 0;

如果不需要UTF-16字符中更奇怪的一半,可以使用
字母
的最高位作为EOW标记

例如,这里的
eoWletterA
变量使用EOW位编码字母“a”:

char eoWletterA = 'a' + 0x8000;
char letter = (char) (eoWletterA & 0x7FFF);
boolean eow = BigInteger.valueOf(eoWletterA).testBit(15);
您的trie应该被正确封装。确保在将字符存储到trie时不会意外设置EOW位


更新:请注意,从节点中删除
boolean
变量可能会或不会对JVM中节点对象的内存占用造成影响。您可以使用以下工具检查对象内存占用情况:

是否可以以面向对象的方式执行此操作,因此您有
endofordnode extends Node
,隐式指示布尔值?@AndyTurner与trys通常的构造方式相同,这可能会使事情更加困难。@immibis“更困难”确定。我宁愿不做。但是,如果空间是最重要的考虑因素,那么解决这个问题的难度可能是价格。为什么需要减少节点的大小?假设一个节点大约有24个字节,而其中有2兆字节。。。如果你能节省6个字节,你就可以节省大约半兆字节。如果节省半兆字节很重要的话,那么Java肯定不是可以使用的语言。哇,伙计,我需要一些时间来理解这段代码)谢谢,我会检查它的谢谢:)如果你有高性能要求,它当然可以优化,并在可读性方面进行权衡。大多数体系结构上都填充了对象和单个字段
char
+
boolean
byte
可能占用单个字。确保测试这一点确实会给您带来可衡量的性能增益。在我的机器上,使用的内存没有差别。@Banthar使用以下答案尝试此操作:。节点对象在我的JVM中是24字节。我注意到,即使删除boolean和char变量,Node对象的内存使用量在我的JVM中仍然保持在24字节。