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

Java 在变量之间传递大数据时最小化内存使用,java,image,memory,loading,pass-by-value,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); // v

我知道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
加载图像,则无论图像有多大,它都不会占用大量内存


这是正确的吗?要避免将同一个超大图像多次加载到内存中,我应该避免哪些陷阱?

你是对的,当你调用
y=x
时,它只需设置
y
来引用“超大图像”的位置。内存中仍然只有一个对象将被
x
y
引用


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

是的,您是对的,对非基本引用变量的任何非基本实例赋值都只是引用赋值

所以,如果x有一个内存位置,比如mem1,那么y=x将使y指向mem1。现在,即使x指向一个新的内存位置mem2,y仍然指向mem1。所以这是一个需要避免的陷阱

您几乎无法多次加载一个非常大的对象而不首先注意到它,因为您可能正在创建调用构造函数的新对象,或者使用某种形式的clone()方法

与大型对象无关但与Java中的引用传递相关的一个陷阱是,传递给方法的引用变量不能被取消引用


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

如果您担心可能会多次使用同一参数调用
new MyImage(“some string”)
,并且它将创建同一大映像的多个副本,然后可以使用缓存来避免问题。
映射
例如
哈希映射
将是维护这种缓存的简单方法。
这是否正确?
-是的,y和x都只保存大对象的内存地址。在大多数系统中,内存地址是一个整数(小)。在您关于取消引用的最后一点中。这是否意味着现在有两个MyTin引用?是的,一个在调用方方法中,一个在调用方法中。在C语言中的其他编译语言中,这是否同样?我不知道C语言,但是从它的外观上看,它就像C和C++,任何引用都是指针,这与java不同。