Java 我应该“新建”循环内还是循环外的对象?

Java 我应该“新建”循环内还是循环外的对象?,java,performance,garbage-collection,jvm,Java,Performance,Garbage Collection,Jvm,比较以下代码中的test1()和test2(): class Test{ //max value is a large number int max_value = 100*1000; public void test1(){ for(int i=0; i<max_value;){ StringBuilder builder = new StringBuilder(); builder.app

比较以下代码中的
test1()
test2()

    class Test{
    //max value is a large number
    int max_value = 100*1000;

    public void test1(){
        for(int i=0; i<max_value;){
            StringBuilder builder = new StringBuilder();
            builder.append("String value");
            builder.append("append our value much time so will consume many memory");
        }
    }

    public void test2(){
        StringBuilder builder = new StringBuilder();
        for(int i=0; i<max_value;i++){
            builder.append("String value");
            builder.append("append our value much time so will consume many memory");
            builder.setLength(0);
        }
    }
}
类测试{
//最大值是一个很大的数字
int max_值=100*1000;
公共void test1(){

对于(int i=0;i,微基准在测试之前对JVM的状态有很大影响

如果要测试您的性能,您一个接一个地运行这两个代码,这会对结果产生很大影响

所以这是不同的呼唤

test1();
test2();

因为在
test1
中使用了整个可用内存,而
test2
需要运行垃圾收集器


对于
setLength
的内部实现,最好使用第二个实现(
test2
),只考虑性能问题

请记住,性能并不是全部。更改
StringBuilder
的长度并不直观,因此从程序员的角度来看,很容易误解第二个实现。通常可读性更强的代码比性能更高的代码好。JVM非常擅长这一点至少在
test1
中有

test2
中,虚拟机可以做的任何优化都会被丢弃,因为它必须在
StringBuilder
中将备份数组归零


但这还不是故事的结尾。微基准测试很难获得正确的结果,而且在每个平台上都不会正确。因此,与其过于担心它们,不如编写可读代码(IMO
test1
)。当探查器告诉您“这是需要花费大量时间的事情”时,就是这样您可以更轻松地对其进行优化。

这取决于代码中如何进一步利用builder对象。这些时间是什么?尝试在不使用
builder.append
的情况下对其进行测试(因为在这两种情况下都会发生)。当我使用test1()时,如果比较调用构造函数和
builder.setLength(0)
,结果如何;我的程序使用时间少于test2(),我的疑问是我在test1()中创建了这么多对象,GC如何恢复它。生成器对象只在每个loop@DarshanMehtaonly一种方法将被调用,有两种方法可以实现我的业务,我怀疑在test1()中哪一种会更好,每次调用此方法时,我都会创建一个对象,GC是否会恢复这些对象以及如何恢复?是test2()比test1()好吗?首先,我认为test2()比test1()好,实际上test2()比test1()需要更多的时间,所以这是我的疑问我知道…但我不知道你是如何测试每种方法的性能的。通常人们创建一个主方法并逐个调用它们。在我的业务中,我们有一个嵌套循环,我需要在内部循环中执行逻辑,内部循环和外部循环都需要循环很多次。垃圾收集只在需要dep时发生以垃圾收集器的参数结束。一个方法可能会占用大量内存,但垃圾收集器不会启动。下一个方法需要更少的内存,但没有可用内存,因此垃圾收集器会开始释放未使用的内存。
test2();
test1();