Java 什么是最节省内存的数据结构,可以满足我的目的?
我正在尝试内存优化我的服务器,它一直运行在OOM中 服务器中的大多数对象(按计数)采用以下形式:Java 什么是最节省内存的数据结构,可以满足我的目的?,java,memory-management,data-structures,hashmap,memory-optimization,Java,Memory Management,Data Structures,Hashmap,Memory Optimization,我正在尝试内存优化我的服务器,它一直运行在OOM中 服务器中的大多数对象(按计数)采用以下形式: 每个对象都是一个HashMap HashMap键是字符串 HashMap值是属性类的对象,属性类只有一个int和两个boolean 重要提示:95%的hashmap只有一个键;我知道在创建hashmap时是否是这样 有数以百万计的散列图 我已经问了另外一个关于优化这些hashmaps内存方面的问题,有人在评论中建议,也许重新设计我的整个数据结构会更好,因为即使初始大小为“1”的hashmaps仍
- 每个对象都是一个HashMap
- HashMap键是字符串
- HashMap值是属性类的对象,属性类只有一个int和两个boolean
注意:我需要能够查找特定值是否作为键存在;因此,我考虑过将数据存储在[string_value,int,boolean,boolean]的五元组列表中,但拒绝了。每个对象都是HashMap?不是很好的抽象概念。我更喜欢组合:创建一个具有哈希映射并提供清晰API的对象。使其具有可比性,并实现hashCode和equals 如果有很多重复的话,我建议你遵循飞锤模式 如果对象是不可变且只读的,那么这将是一个非常好的优化 使用Factory对象创建实例并维护唯一实例的列表。如果有人要求提供列表中已有的副本,请返回不可变副本
在实现之前,您可以计算这将节省多少内存。向用户公开不太具体的
Map
接口,而不是HashMap
,这使您可以根据具体情况自由使用hash映射或单例映射
可以通过集合创建节省内存的单例映射。单例映射()
:
SingletonMap
似乎是作为一个对象实现的,只有两个字段和一些缓存:
p、 在美国,通过将映射和值折叠为一个实例,您可以为您的特殊情况提供更紧凑的内容,如下所示:
public final class SingletonAttributeMap extends Attribute implements Map<String,Attribute> {
private final String key;
public Attribute get(String key) {
return this.key.equals(key) ? this : null;
}
....
}
public final类SingletonAttributeMap扩展属性实现映射{
私有最终字符串密钥;
公共属性get(字符串键){
返回this.key.equals(key)?this:null;
}
....
}
p、 另外,属性中的整数是否有最大大小?您可能可以执行类似的操作(这是否真正节省内存取决于填充/对齐,请参阅):
类属性{
私有int值;
布尔getBoolean1(){
返回值(值&1)!=0;
}
布尔getBoolean2(){
返回值(值&2)!=0;
}
int getInt(){
返回值>>2;
}
void setBoolean1(布尔值b){
value=(value&~1)|(b?1:0);
}
void setInt(int i){
value=(value&~3)|(我可以在创建地图后更改地图键吗?@JohnKugelman-否。值“attribute”对象有时可以更改,但不能更改键。作为旁白,初始问题中的某个人提到了singletonMap。如果这是一个好答案,我希望有人能提供实际的线索“这是一个常规HashMap需要多少内存,这是一个singletonMap需要多少内存“这是一个自制的类/对象系统吗?如果是这样,你可以通过让类有字符串来索引映射,而对象只有值数组来节省大量内存。@DVK:你不需要对每个映射使用相同的映射类。问题是什么样的结构节省了最多内存。“你可以计算”似乎表明它的内存性能可能更差。当我说“你可以计算”时,我的意思是你可以查看今天的数据并回答“这是我可以分发多少Flyweight不可变实例,而不必在内存中复制对象。”关键是不可变的数据和大量的重复。如果这两个假设都是真的,那么如果你按照我的建议做,你将节省大量内存。好的,就像我经常遇到的情况一样,我足够聪明,可以使用模式位,但不够聪明,不知道我正在使用命名模式:)在你发布答案的时候,我为我的属性做了Flyweight的事情,只是不知道它是什么。它节省了一些内存,但显然不够。我不确定你所说的HAS-A hashmap是什么意思?你是说我只将1个值存储为一个成员和hashmap(如果只有1个值,则为null)作为另一个成员?我的意思是将实现细节封装在一个对象中,而不是使用原始HashMap。尽可能多地存储,但是通过保证正确操作的公共方法来存储。
class Attribute {
private int value;
boolean getBoolean1() {
return (value & 1) != 0;
}
boolean getBoolean2() {
return (value & 2) != 0;
}
int getInt() {
return value >> 2;
}
void setBoolean1(boolean b) {
value = (value & ~1) | (b ? 1 : 0);
}
void setInt(int i) {
value = (value & ~3) | (i << 2);
}
...