怎么设计JAVA类,消耗的内存最小?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么设计JAVA类,消耗的内存最小?相关的知识,希望对你有一定的参考价值。
怎么设计JAVA类,消耗的内存最小?
类成员里少使用多占内存的成员,如Map、Vector、Array等。如果不是太复杂,能用基本数据类型表示的应该使用基本数据类型。压缩不必要的数据,类成员只要关键量,非关键量全部去掉。
精减算法和运算,如使用复合赋值代替普通运算,条件运算代替if语句。
减少内存占用并不是程序必须的目标,通常程序的几个指标都是相互冲突的。
内存占用少了,往往程序可读性下降,运行效率减少。很少有完美的解决方法的。来自:求助得到的回答 参考技术A 非常同意楼上。
减少内存使用最主要的方法当然是设计特定的算法,就拿网页上常常使用的分页列表来说,一般有两种方式,真分页和假分页,真分页内存占有比假分页少很多,但是当数据量不大的时候我们还是会采用假分页,虽然第一次读取慢一点,内存使用大一些,但是这之后查询就比真分页快很多了。所以好的程序,并不是内存使用越少越好。 参考技术B 留个位置学习一下
如何最小化 Protobuf.NET 内存消耗
【中文标题】如何最小化 Protobuf.NET 内存消耗【英文标题】:How to minimize Protobuf.NET memory consumption 【发布时间】:2011-10-25 16:07:07 【问题描述】:我正在使用 Protobuf.NET 序列化大量类,其中大部分作为引用(因为我的数据结构中有多个对相同类的引用)。
所有序列化的类都通过使用 ImplicitFirends.AllFields 进行序列化,以确保 一切都被倾倒了。
在我当前的测试用例中,我有 53 个文件,总和为 500MB。
当我使用 Protobuf.NET 反序列化器读取此数据时,我的私有字节/常驻内存会飙升至 9GB 并停留在那里(即,这不是在反序列化后释放/GC 的临时内存)。
另一个奇怪的事情是,如果我重写(重新序列化)所有数据,它仍然保持相同的大小。
这个 x20 在内存中爆炸有意义吗?
【问题讨论】:
【参考方案1】:我将运行一些测试,但它听起来就像是它为避免分配而保留的缓冲池。除了测试之外,我将在下一个版本中添加一个“转储池”方法(并禁用?)。其实想一想:我会把这些改成WeakReference
,这样它们就可以在它们存在的时候被重新使用,但仍然被收集起来。
您可能还会发现(作为合同的一个选项)对子对象和列表使用“组”编码可以大大减少这里的内容; length-prefixed 是默认值(也是 Google 的首选选项),但组的写入效率更高,因为它们可以直接写入而无需任何缓冲。让我知道你是否想要一个这样的例子。 Protobuf-net 的设计使得它们之间的切换不是一个重大变化,但 other protobuf 客户端不会那么宽容,如果您使用 protobuf 与其他系统进行互操作,那就更棘手了。
【讨论】:
我不确定这真的是缓冲池。当我转储堆时,我看到了多个(即 10,000 或更多)类实例,这些实例应该在个位数范围内。有没有办法验证 AsReference “功能”是否真的有效?我有一个特定的类被设置为被编码为 AsReference,我实际上应该有其中之一,但我似乎有超过 10,000 个......这让我怀疑 AsReference 功能...... @damageboy 从您的数据中验证肯定很容易 - 只需调用 ReferenceEquals。如果您可以展示您的场景的一个小示例,这将有所帮助,请注意,引用仅在单个图形操作期间有效 - 如果您分别调用 Deserialize 5 次,仍然是 5 个对象,而不是一个。是这里的情景吗?我是这样的,可能还有其他选项(包括我多年来一直想要实现的核心 .NET 引用交换接口,它可能允许你做你想做的事)。 我想我正在解决这个问题...如果我有一个继承方案,其中 C 派生自 B,而 B 派生自 A...是否应该将所有这些类标记为参考? 嗨,Marc,我的情况似乎有些复杂。我用“AsReference”标记的一些类确实被序列化为引用并通过了 ReferenceEquals 测试,而其他更复杂的类,可能具有继承的那些类不,并且基本上被复制......在有关的场景中支持 AsReference子类型和继承? @damageboy 应该是,但这很复杂。我必须测试。以上是关于怎么设计JAVA类,消耗的内存最小?的主要内容,如果未能解决你的问题,请参考以下文章