我最近在代码中发现了这样一个问题 - 基本上是有人试图创建一个大对象,但当没有足够的堆来创建它时就会复制:
try {
// try to perform an operation using a huge in-memory array
byte[] massiveArray = new byte[BIG_NUMBER];
} catch (OutOfMemoryError oome) {
// perform the operation in some slower but less
// memory intensive way...
}
这似乎不正确,因为Sun公司本身建议您不要尝试捕获Error
或其子类。我们讨论了这个问题,并提出了另一个想法,即明确检查空闲堆:
if (Runtime.getRuntime().freeMemory() > SOME_MEMORY) {
// quick memory-intensive approach
} else {
// slower, less demanding approach
}
再次说明,这似乎不太令人满意 - 特别是在选择SOME_MEMORY
的值时,很难将其与所需的工作轻松关联起来:对于某些任意大的对象,我怎么能估计它的实例化可能需要多少内存?
有更好的方法吗?在Java中是否可能进行这样的管理,或者任何管理语言本身抽象级别以下的内存的想法都不可能?
编辑1:在第一个示例中,估计给定长度的byte[]
可能占用的内存量实际上是可行的,但是否存在一种更通用的方式,适用于任意大的对象?
编辑2:正如@erickson指出的那样,有办法在创建对象后估算其大小,但(忽略基于先前对象大小的统计方法)是否有一种方法可以为尚未创建的对象执行此操作?
还有一些争论,即捕获OutOfMemoryError
是否合理 - 有人了解任何确凿的事情吗?