我想知道更好的内存管理编码方式,
方法1:
Obj temp;
public static Obj fun1() {
......
......
Obj temp = new Obj();
return temp;
}
方法2:
public static Obj fun1() {
........
.........
return new Obj;
}
哪种方法会好?两种方法都做同样的工作。但是第二种方法返回创建新的Object
,而第一种方法create Object
将其存储在变量中并返回变量。
请考虑我的函数将返回大量此类函数返回不同类的Object
。并且在执行自动测试程序期间会多次调用它们。我应该使用哪一个?为什么?
答案 0 :(得分:2)
使用单例模式。如果可以跨越相同的实例,则创建一次静态对象 它就像
static Object temp;
public Object getObjectInstance(){
if(temp==null){
temp = new Object();
}
return temp;
}
答案 1 :(得分:0)
两种方式都可以,并且对内存产生同样的影响。如果要在返回函数之前对函数内部的对象执行某些操作,则使用第一个。第二个假设您不想这样做。
答案 2 :(得分:0)
回答:您指定的两种方法存在非常小的差异。您也知道,在这两种方法中都会创建一个新对象,因此适合您。现在您担心在第二种方法中将使用一个新变量来存储对象引用 - 但它确实无关紧要,因为只要方法结束,该方法创建的所有局部变量都将从堆栈中删除。
<强>概念强>
简而言之:对于您提供的方法,在内存管理方面几乎没有任何差异。
答案 3 :(得分:0)
字节码中存在实际差异。我们来看下面的课程。
public class Test {
public static void main(String... args) {
final int LIMIT = 10_000_000;
final int RUNS = 10;
for (int run = 0; run < RUNS; ++run) {
Test[] t = new Test[LIMIT];
long start = System.nanoTime();
for (int i = 0; i < LIMIT; ++i) {
t[i] = fun1();
}
System.out.println( "fun1: "
+ ((System.nanoTime() - start) / 1_000_000_000d)
+ "s");
t = new Test[LIMIT];
start = System.nanoTime();
for (int i = 0; i < LIMIT; ++i) {
t[i] = fun2();
}
System.out.println( "fun2: "
+ ((System.nanoTime() - start) / 1_000_000_000d)
+ "s");
}
}
public static Test fun1() {
return (new Test());
}
public static Test fun2() {
Test t = new Test();
return (t);
}
}
当您查看方法fun1()
和fun2()
的字节码时,它们将如下所示:
public static Test fun1();
Code:
0: new #1 // class Test
3: dup
4: invokespecial #20 // Method "<init>":()V
7: areturn
public static Test fun2();
Code:
0: new #1 // class Test
3: dup
4: invokespecial #20 // Method "<init>":()V
7: astore_0 // those lines are
8: aload_0 // unique to fun2()
9: areturn
执行此代码时,您可能会注意到执行时间越来越快。我认为这是由于JIT编译器。然而,最终,在绩效方面几乎没有差异。
答案 4 :(得分:0)
这两种方法几乎相似。在方法1中,如果在将对象分配给引用变量后立即返回,则将其分配给refence变量没有意义。在这种情况下,方法2应该选择。
Obj temp = new Obj(); //if you are not doing anything with temp but just returning then go with method 2
return temp;
但是如果你必须改变对象或者做一些操作,那么method1应该是好的,因为你将在'temp'中获得对该对象的引用
Obj temp = new Obj(); //if temp is used before return, then go with method 1
return temp;
注意:只有对象占用堆上的内存而不是引用变量。
答案 5 :(得分:0)
我和专家讨论过,发现每次创建新对象时,使用以下方法都会在堆栈中创建内存分配。
method1 () {
return new ClassObj();
}
method2 () {
return new ClassObj();
}
method3 () {
return new ClassObj();
}
method4 () {
return new ClassObj();
}
method5 () {
return new ClassObj();
}
并且这个堆栈内存继续分配。如果我们在运行期间多次调用此函数(因为它通常在运行自动脚本中发生)同一个函数一次又一次地调用多次,这个堆栈的累积会继续增加。
所以为了避免这种情况,请使用一些临时对象来捕获方法返回的对象。因此,不是在堆栈中分配内存,而是删除临时对象的先前内存数据并将其替换为新的。
ClassObj temp;
method1 () {
temp = new ClassObj();
return temp;
}
method2 () {
temp = new ClassObj();
return temp;
}
method3 () {
temp = new ClassObj();
return temp;
}
method4 () {
temp = new ClassObj();
return temp;
}
method5 () {
temp = new ClassObj();
return temp;
}