`
阅读更多
1.Java 性能优化之创建对象
对于每个java程序员都知道怎样创建对象,但是你知道怎样创建才能提高应用的性能呢?
你知道创建对象的应用规则吗?
(1).要尽量避免在循环体中创建对象.
(2).尽量及时使对象符合垃圾回收标准.
(3).不要采用过深的继承层次.
(4).访问本地变量优于访问类中的变量.
例如:
Vector v=new Vector();
for(int i=0; i<100;i++){
Object obj=new Object();

}
这样的写法大家都不陌生吧。可是这样会浪费大量的内存空间。正确的方法如下。
Vector v=new Vector();
Object obj=null;
for(int i=0; i<100;i++){
obj=new Object();

}
这样内存中保存一个对象的引用,从而减少了浪费内存空间的情况。

还有:
不要对一个对象进行多次初始化。这样也会带来较大的内存开销,相抵系统性能。
public class Test(){
    private HashMap map=new HashMap();
    public Test(){
        map=new HashMap()
   }
}
以上的几点都好理解。可是有很多新手会出现上面的问题哦!!!!
分享到:
评论
19 楼 b051 2008-02-28  
关键还是垃圾回收机制。你把变量直接引用新实例,只是积极地告诉jvm去回收之前的实例。出了循环体,jvm一样知道需要回收的。其实很难讲具体的jvm和jvm参数下,这样做是否更好。
另一方面,原则上,循环中的变量会比外边的快,就好像方法里的变量会比类里的快,类里的会比全局的快,一个道理。只是太快了以至于看不出来而已。
18 楼 wutao8818 2008-02-28  
说的不错~
17 楼 shikonglaike 2008-02-28  
真的很高兴看到这么多同行的发言!
真对这个问题提我还想知道这两种方式。垃圾回收器对对象的回收相同吗。
16 楼 香克斯 2008-02-28  
在没有实际测试之前不需要所谓的这种从写代码上面来进行的优化。只要你的代码写得够清晰,等出问题的时候回头优化也不晚。而且现在虚拟机的优化已经挺不错了,写程序是过于考虑这些也就是一种杞人忧天的行为
15 楼 bigcatJavaEye 2008-02-28  
LZ的第一条赞成。
尽量不要再loop里面new对象。
所举的例子可能不太符合提议。
1 loop中并没有减少对象的new,只是减少了引用的开销,而一个引用就几个字节。
2 楼上有人说了,现在的jvm已经可以优化了。
   下面的例1可以看出来,系统只是在第一次创建很多引用,以后他就偷懒了。
    例2进一步可以证明,如果内存中已经存在很多引用的话,他也会偷懒。

测试了一下。
例1
import java.util.Date;

class test{
    public static Runtime rt = Runtime.getRuntime();
    public static void main(String[] args){

    	for(int i=0;i<5;i++){
        	System.out.println("getUseredMemorySize1:" + getUseredMemorySize1());
        	System.out.println("getUseredMemorySize2:" + getUseredMemorySize2());
        	System.out.println("-------------------------------------------------");
    	}
    }
    
    public static Long getUseredMemorySize1(){
    	Long size = rt.freeMemory();
    	for(int i=0;i<1000;i++){
    		Date d = new Date();
    	}
    	return size - rt.freeMemory();
    }
    
    public static Long getUseredMemorySize2(){
    	Long size = rt.freeMemory();
    	Date d = null;
    	for(int i=0;i<1000;i++){
    		d = new Date();
    	}
    	return size - rt.freeMemory();
    }
    
}

输出结果:
-------------------------------------------------
getUseredMemorySize1:20784
getUseredMemorySize2:6312
-------------------------------------------------
getUseredMemorySize1:6096
getUseredMemorySize2:6000
-------------------------------------------------
getUseredMemorySize1:6096
getUseredMemorySize2:6000
-------------------------------------------------


例2 提前放点引用到jvm
    public static void main(String[] args){

[color=red]    	for(int i=0;i<1000;i++){
    		Date d = new Date();
    		d.setDate(2);
    	}[/color]
    	for(int i=0;i<5;i++){
        	System.out.println("getUseredMemorySize1:" + getUseredMemorySize1());
        	System.out.println("getUseredMemorySize2:" + getUseredMemorySize2());
        	System.out.println("-------------------------------------------------");
    	}
    }

输出
-------------------------------------------------
getUseredMemorySize1:6696
getUseredMemorySize2:6312
-------------------------------------------------
getUseredMemorySize1:6096
getUseredMemorySize2:6000
-------------------------------------------------
getUseredMemorySize1:6096
getUseredMemorySize2:6000
-------------------------------------------------
14 楼 coder1982 2008-02-28  
我个人的分析如下:
第一种模式:
Vector v=new Vector(); 
for(int i=0; i<100;i++){ 
Object obj=new Object(); 

} 

Object 只是每次循环的时候声明了一次引用,但这个引用每次在程序执行到“}”的时候就没了,它是局部变量,等到循结束后,Object的任何对象都不会存在了。


第二种模式:
Vector v=new Vector(); 
Object obj=null; 
for(int i=0; i<100;i++){ 
obj=new Object(); 

} 

看似只声明了一次引用,其实有大大不妥。因为循环结束后,obj仍然还保留着对象。等到下次再执行到"}"时,其对象才会释放。当然,手动的话就再来一次obj=null;

综合来说,我觉得应该根据使用场景不同,来合理使用两种方法。优化代码不单单是减少创建对象,合理控制对象的生命周期和作用域,也是必要的考虑环节。
13 楼 mllee 2008-02-28  
movingboy 写道
有没有哪位能用测试数据说话?



试试看,一样的。
但像楼上所说,变量声明在块里面可以把变量作用域限制得更小,所以还是声明在里面好。
也赞成之前的说法,在前面再加一行 Object obj = null 不美观。


public class Test
{
	public static class A
	{
		private byte[] memoryBlock = new byte[5 * 1024 * 1024];
	}
	
	public static void main(String[] args) throws Exception
	{
		final int LOOP_COUNT = 20;
		final long SLEEP_MILLIS = 3000;
		
		System.out.println("please open windows task manager and monitor the memory usage...");
		Thread.sleep(SLEEP_MILLIS);
		
		System.out.println("variable in for loop...");
		for (int i = 0; i < LOOP_COUNT; ++i)
		{
			A a1 = new A();
		}
		Thread.sleep(SLEEP_MILLIS);

		System.out.println("variable out of for loop...");
		A a2 = null;
		for (int i = 0; i < LOOP_COUNT; ++i)
		{
			a2 = new A();
		}
		Thread.sleep(SLEEP_MILLIS);

		System.out.println("exit!");
	}
}
12 楼 vchengyun 2008-02-28  
我以前做过类似的测试。

第一种以第二种速度快,内存没测过

即尽量用Object obj=new Object();
还可以减小变量的域。
11 楼 movingboy 2008-02-27  
shikonglaike 写道
当然有区别了。第二种在内存中保存一个对象的引用,而第一种的编码方式会在内存中产出大量的对象。浪费大量的内存空间,还有也增加了系统做垃圾回收的负荷。仔细想想是不是这样。

记得不太清晰了,但猜测现在的编译器或虚拟机已经比较先进,应该能够对第一种情况进行优化
10 楼 movingboy 2008-02-27  
有没有哪位能用测试数据说话?
9 楼 yyjn12 2008-02-27  
luanma 写道
Object obj=null;
for(int i=0; i<100;i++){
  obj=new Object();

}

没必要,而且难看


有必要的.狮子说的对呢.
一个引用要占4个字节的内存呢.
8 楼 luanma 2008-02-27  
Object obj=null;
for(int i=0; i<100;i++){
  obj=new Object();

}

没必要,而且难看
7 楼 shikonglaike 2008-02-27  
大家说的很好!
你们的意思是这两个一样了?
6 楼 EXvision 2008-02-27  
求达人解释下,我也一直以为第一个例子的第二种写法好。。寒
5 楼 shikonglaike 2008-02-27  
mvmouse 写道
这两段代码都创建了100个一般对象和1个Vector,占用的内存为什么不一样呢?
所谓浪费大量的内存空间浪费在哪里了呢?


上一个有一百个引用.下一个有一个引用.
4 楼 mvmouse 2008-02-27  
这两段代码都创建了100个一般对象和1个Vector,占用的内存为什么不一样呢?
所谓浪费大量的内存空间浪费在哪里了呢?
3 楼 edu 2008-02-27  
shikonglaike 写道
当然有区别了。第二种在内存中保存一个对象的引用,而第一种的编码方式会在内存中产出大量的对象。浪费大量的内存空间,还有也增加了系统做垃圾回收的负荷。仔细想想是不是这样。

我觉得,第二种方法在内存里面同样保留大量对象的匿名引用
2 楼 shikonglaike 2008-02-27  
当然有区别了。第二种在内存中保存一个对象的引用,而第一种的编码方式会在内存中产出大量的对象。浪费大量的内存空间,还有也增加了系统做垃圾回收的负荷。仔细想想是不是这样。
1 楼 tinywind 2008-02-27  
第一个例子有区别吗?

相关推荐

    java性能优化教程

    Java性能优化是提升软件效率和用户体验的关键环节,尤其是在大规模应用和高并发场景中。本教程将深入探讨如何通过各种技术和策略来优化Java程序,确保其高效运行。 首先,理解Java性能的基础是JVM(Java虚拟机)。...

    大话JAVA性能优化

    《大话JAVA性能优化》这份文档深入探讨了Java程序在多个层面的性能调优策略,旨在帮助开发者提高程序运行效率,降低资源消耗,提升用户体验。以下是对这些知识点的详细阐述: 1. **代码层次优化**:在代码编写阶段...

    Java性能优化实战视频全集

    ### Java性能优化实战知识点概述 #### 一、理论分析篇 **1.1 性能优化的衡量指标及注意事项** - **衡量指标**: 包括响应时间、吞吐量、资源利用率等。 - **注意事项**: 在进行性能优化时,需确保优化方案不会引入...

    Java 性能优化实战 21 讲2021年

    │ 开篇词 Java 性能优化,是进阶高级架构师的炼金石.mp4 │ 02 理论分析:性能优化有章可循,谈谈常用的切入点.mp4 │ 03 深入剖析:哪些资源,容易成为瓶颈?.mp4 │ 04 工具实践:如何获取代码性能数据?....

    java性能优化

    【Java性能优化】是开发者关注的重要话题,尤其是在服务器端应用中。Java自1990年代中期诞生以来,虽然凭借其跨平台特性受到欢迎,但性能一直是与C++等语言相比的一个短板。本文将从几个关键方面探讨Java性能优化。 ...

    大话java性能优化 周明耀 完整版

    《大话java性能优化》是周明耀先生的一本深入探讨Java性能调优的专业书籍,其主要内容涵盖了Java程序设计中的各种性能优化策略和技术。这本书旨在帮助开发者理解和掌握如何提升Java应用的运行效率,减少资源消耗,...

    Java 性能优化 一书源码

    Java性能优化是软件开发中的一个关键领域,尤其是在大型企业级应用和高并发系统中。《Java性能优化》一书深入探讨了如何通过各种技术提升Java应用程序的效率和响应速度。以下是一些基于书籍源码和相关文件名的关键...

    大话Java性能优化.epub

    大话java性能优化,pdf版!

    阿里JAVA性能优化实战

    【阿里JAVA性能优化实战】是面向Java开发人员和架构设计人员的专业课程,旨在提供系统优化的知识和技巧。本文将深入探讨Java性能优化的关键点,并基于给出的部分内容进行详细阐述。 性能调优对于任何互联网公司都是...

    JAVA性能优化手册

    JAVA性能优化查看Linux服务器内存使用情况,JVM参数设置、分析

    Java性能优化的45个细节.pdf

    根据提供的文件信息,以下是关于Java性能优化的详细知识点,内容包括单例模式的合理应用、静态变量的使用考量、对象创建与垃圾回收策略、final修饰符与内联优化、局部变量与实例变量的性能差异、包装类型与基本类型...

    10种java性能优化方案.docx

    ### Java性能优化方案详解 #### 一、理解性能优化的重要性 在现代软件开发中,特别是在Java领域,性能优化是一项至关重要的任务。随着系统的复杂性和规模不断增长,优化不仅仅是提高用户体验那么简单,更是确保...

    大话JAVA性能优化.pdf

    大话Java性能优化》主要提供Java性能调优方面的参考建议及经验交流。作者力求做到知识的综合传播,而不是仅仅只针对Java虚拟机调优进行讲解,另外力求每一章节都有实际的案例支撑。具体包括:性能优化策略、程序编写...

    Java性能优化技巧集锦

    Java性能优化是提升软件效率和用户体验的关键步骤,涵盖了多种技术和策略。本文将深入探讨Java通用篇、J2EE篇、GUI篇、EJB篇以及缓存优化等方面的知识点,旨在帮助开发者实现更高效的代码。 一、Java通用篇 在Java...

    大话Java性能优化

    具体 包括: 性能 优化 策略、 程序 编写 及 硬件 服务器 的 基础 知识、 Java API 优化 建议、 算法 类 程序 的 优化 建议、 并行 计算 优化 建议、 Java 程序 性能 监控 及 检测、 JVM 原理 知识、 其他 相关 ...

Global site tag (gtag.js) - Google Analytics