Java 在以后的方法调用中保留对对象的引用,或在长方法中每次提取对象 A类{ void method1(){ B=新的B(); C=新的C(); //选择1 List cachedObject=b.method1(); c、 方法1(缓存对象); c、 方法2(缓存对象); //选择2 c、 方法1(b.方法1()); c、 方法2(b.方法1()); } } B类{ 列表方法1(){ } } C类{ 无效方法1(列表a){ } 无效方法2(列表a){ } }

Java 在以后的方法调用中保留对对象的引用,或在长方法中每次提取对象 A类{ void method1(){ B=新的B(); C=新的C(); //选择1 List cachedObject=b.method1(); c、 方法1(缓存对象); c、 方法2(缓存对象); //选择2 c、 方法1(b.方法1()); c、 方法2(b.方法1()); } } B类{ 列表方法1(){ } } C类{ 无效方法1(列表a){ } 无效方法2(列表a){ } },java,garbage-collection,Java,Garbage Collection,在选项2中,c.method1()的参数在返回后是否可用于垃圾收集?与选项1相比,在选项1中,我们缓存对象并在方法调用c.method1()和c.method2()中使用它,考虑到c.method1()和c.method2()之间发生了耗时的操作调用,因此缓存的对象在此期间仍被引用,并且不可用于垃圾收集 从内存利用率的角度来看,考虑到b.method1()返回的对象是巨大的(500MB+),哪个选项更合适?内存利用率和性能之间有一条细微的界限。正确的答案取决于你的情况。以下是我想问的一些问题

在选项2中,c.method1()的参数在返回后是否可用于垃圾收集?与选项1相比,在选项1中,我们缓存对象并在方法调用c.method1()和c.method2()中使用它,考虑到c.method1()和c.method2()之间发生了耗时的操作调用,因此缓存的对象在此期间仍被引用,并且不可用于垃圾收集


从内存利用率的角度来看,考虑到b.method1()返回的对象是巨大的(500MB+),哪个选项更合适?

内存利用率和性能之间有一条细微的界限。正确的答案取决于你的情况。以下是我想问的一些问题

  • 你的记忆限制是什么?保留此对象是否会导致JVM耗尽堆空间
  • 您的性能要求是什么?创建此对象是否需要一段时间,并且重新创建它是否会将应用程序的速度降低到不可接受的程度
  • 垃圾收集永远无法得到保证,那么在内存中同时存在这两个对象的风险是什么呢
  • 您需要使用此对象多少次/位置?它会在单独的线程上传递并异步使用,还是在使用之间会有很大的差距

我提供的一个解决方案是查看Java的
WeakReference
类。此类允许您维护对不阻止垃圾收集的对象的弱引用。无论何时您想要使用它,您都会执行空检查,如果它是垃圾收集的,您可以重新创建它。当您绝对不希望在内存中有多个大型对象的实例时,这是非常有用的,因为只有在旧引用被垃圾收集后,弱引用才会为null。

在内存利用率和性能之间有一条很好的界限。正确的答案取决于你的情况。以下是我想问的一些问题

  • 你的记忆限制是什么?保留此对象是否会导致JVM耗尽堆空间
  • 您的性能要求是什么?创建此对象是否需要一段时间,并且重新创建它是否会将应用程序的速度降低到不可接受的程度
  • 垃圾收集永远无法得到保证,那么在内存中同时存在这两个对象的风险是什么呢
  • 您需要使用此对象多少次/位置?它会在单独的线程上传递并异步使用,还是在使用之间会有很大的差距

我提供的一个解决方案是查看Java的
WeakReference
类。此类允许您维护对不阻止垃圾收集的对象的弱引用。无论何时您想要使用它,您都会执行空检查,如果它是垃圾收集的,您可以重新创建它。当您绝对不希望在内存中有多个大型对象实例时,这非常有用,因为只有在旧引用被垃圾收集后,弱引用才会为null。

可以肯定的是,垃圾收集不会因为耗时的操作而发生。。它取决于所持有对象的引用类型。对于这样一个一般性问题,答案几乎是“它取决于”。根据一个或另一个性能指标,可能会出现更好的情况。可以肯定的是,垃圾收集不会因为耗时的操作而发生。。它取决于所持有对象的引用类型。对于这样一个一般性问题,答案几乎是“它取决于”。根据一个或另一个性能指标,我们可以想象出其中一个更好的场景。当我们使用选项2时,我们在生产中遇到了一个问题。对象的创建非常耗时(从数据存储中获取),而且对象的大小很大。当多个线程开始调用该方法时,我们在每次方法调用中创建了如此大的对象(也创建了两次),很快我们的服务器就因为OOM而死掉了。转到选项1会提高性能,但我想知道它是否会使内存利用率降低。您的问题太简单,无法表示复杂的生产环境。最好只是尝试测量差异,而不是猜测可能发生的情况。我们在使用选项2时遇到了生产问题。对象的创建非常耗时(从数据存储中获取),而且对象的大小很大。当多个线程开始调用该方法时,我们在每次方法调用中创建了如此大的对象(也创建了两次),很快我们的服务器就因为OOM而死掉了。转到选项1会提高性能,但我想知道它是否会使内存利用率降低。您的问题太简单,无法表示复杂的生产环境。最好只是试着衡量差异,而不是猜测可能会发生什么。
class A {
    void method1() {
        B b = new B();
        C c = new C();

        // Option 1
        List<Object> cachedObject = b.method1();
        c.method1(cachedObject);
        c.method2(cachedObject);

        // Option 2
        c.method1(b.method1());
        c.method2(b.method1());
    }
}

class B {
     List<Object> method1() {
     }
}

class C {
     void method1(List<Object> a) {
     }

     void method2(List<Object> a) {
     }
}