在变量之间传递大数据时最小化内存使用量

时间:2016-01-02 05:17:07

标签: java image memory loading pass-by-value

我知道Java被传递引用或传递值的问题正在打败死马,但我确实有一个关于内存使用的问题。

我现在理解Java的方式是:

public class MyInt{
    int value;
}

MyInt x;
MyInt y;
x = new MyInt(3);    // value of x is now 3
y = x;               // y now points to same object that x points to
y.setValue(1);       // value of said object is now 1
x.getValue();        // should return 1 instead of 3

但我的问题是如何设置这个新y的内存密集型?例如:如果MyInt的值是非常大的图像而不是整数,

x = new MyImage("very large image");   // eats memory depending on size of image

如果图像非常大,自然会占用大量内存。我只想确保当我打电话时

    y = x; // y now points to same image that x does

y只是对x已经指向右边的对象的引用?所以当我打电话给y = x;只要通过初始化x已经加载了该图像,无论图像有多大,它都不会占用大量内存。

这是对的吗?我应该避免哪些陷阱,以防止同一个非常大的图像被多次加载到内存中?

2 个答案:

答案 0 :(得分:3)

是的,你是对的,对非原始引用变量的任何非原始实例赋值只是引用赋值。

因此,如果x的内存位置为mem1,则y = x将使y指向mem1。现在,即使x指向新的内存位置mem2,y仍将指向mem1。所以这是一个需要避免的陷阱。

你几乎永远无法在不首先注意到它的情况下多次加载一个非常大的对象,因为你要么创建调用构造函数的新对象,要么使用某种形式的clone()方法。

与大型对象无关但与Java中的引用传递相关的一个缺陷是传递给方法的引用变量无法解除引用。

假设有一个方法dereferenceMe(MyInt x) {x = new MyInt();},它不会在调用方法中更改x的实际引用。由于Java将按值传递引用,这意味着它会创建引用变量的副本,并将该副本传递给方法。

答案 1 :(得分:0)

你是对的,当你致电y=x时,它只会设置y来引用"非常大的图像"的位置。内存中只有一个对象可供xy引用。

为避免在内存中反复加载非常大的图像,请不要再次使用该图像创建新对象。避免对象的深层复制。