`

JVM创建一个新对象到底有多大的代价?

阅读更多

        好像是在听一人讲JVM性能调优方面事时, 知道了尽量减少JVM创建对象,因为那样会消耗不少资源. 有了这样的mindset后,自己编码也就尽可能地少创建对象了.

        但看jBPM时,发现每一个请求都要创建一个JbpmContext对象,纳闷的同时也反思先前的那个mindset的正确性,或者说在什么条件下是正确的.

        想到一个例子: Hibernate从数据库取出数据后,都是要以对象的形式来封装的, 那样的每次DB操作至少要创建一个对象的. 这样一想,JbpmContext的创建相比于Hibernate操作DB时对象的创建就可以忽略了.

        做个暴力实验来看下, 创建新对象时JVM的耗时:

        实验用的代码很简单, 如下所示:

for(int i=0;i< 10000;i++) {
	new Object();
}
 



    实验结果如下:

循环次数(也就是创建Object实例的次数)     耗时(毫秒)
1000000000                                             22094
100000000                                                 2282
10000000                                                     219
1000000                                                         31
100000                                                             0
10000                                                               0

现在用的机器配置: Pentium(R) 4 CPU 2.40GHz, 1G内存, 操作系统是 Windows XP(2002版本), SP3.

    从上面的结果看出: 只有在100万次时才有明显的耗时,而这时的耗时也才只31毫秒,而我做实验的机子很破的. 这样在真正的项目中,也就不必多考虑新建一个对象时的耗时了.

    这里只是做了个耗时的实验, 这个耗时背后又倒底做了些什么? 又有哪些是耗时的主犯呢? 抛砖引玉, 期待大家的讨论.

分享到:
评论
8 楼 ZangXT 2009-08-07  
按照gc group的一个报告:
Typically, object allocation is very cheap!
● 10 native instructions in the fast common case
● No remembered set overhead on new objects
● C/C++ has faster allocation? Not!
● Reclamation of new objects is very cheap too!
● Young GCs in generational systems
● So
● Do not be afraid to allocate small objects for
intermediate results
● GCs love small, immutable objects
● Generational GCs love small, short-lived objects

用Object对象测估计说明不了多大问题。

[url]
http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2906.pdf
[/url]
7 楼 rmn190 2009-04-14  
The common code path for new Object() in HotSpot 1.4.2 and later is approximately 10 machine instructions. (from: http://www.ibm.com/developerworks/java/library/j-jtp09275.html?S_TACT=105AGX52&S_CMP=cn-a-j)
6 楼 wendong007 2009-04-08  
如果是比较复杂的对象的,如果构造方法本身的执行方法本来就很长呢
5 楼 量产型人型自走炮 2009-04-02  
JVM没测试过
但是在flash的VM中创建对象的开销貌似是挺大的
我曾经写过一个AIR的本地播放器类似这种
http://222.243.146.200/html/anime/20090402/25579.html
结果是把所有评论在加载时全部创建为控件对象
比加载时存为字符串在播放时动态创建与释放控件(在同一时间需要创建的弹幕数量比教大时)要流畅得多
当然这里的控件的创建开销不是一个object能比的
4 楼 sulong 2009-04-02  
垃圾收集已经针对大量的短命对象优化过了。创建大量的这样的对象对性能没有太大的影响。
3 楼 RednaxelaFX 2009-04-02  
如果是用Sun Hotspot的话,可以开-XX:+PrintGCDetails开关来观察到底GC在什么时候做了什么事。

跟随楼主,测试这样一段代码:
public class TestObjectCreation {
    private static void foo() {
        final int MAX = 10000000;
        for (int i = 0; i < MAX; ++i) {
            new Object();
        }
    }
    
    public static void main(String[] args) {
        foo();
    }
}


查看JIT出来的结果,感觉挺意外的。foo()方法基本上没被优化,i放在了EBX里,每个循环规规矩矩的递增;循环体内的new Object()也规规矩矩的每次都被调用。我原本来以为在方法足够热的时候,Hotspot能把这个新建对象的动作优化掉的。看来要么是这个方法还不够热,要么是……我也不清楚,没读过那部分源码。
2 楼 抛出异常的爱 2009-04-02  
GC时间?
1 楼 sulong 2009-04-02  
除了真的进行复杂的科学计算,否则普通的应用,性能瓶颈一般都发生在IO上,这IO包括,读写磁盘,socket,等。IO操作的代码往往会成为那个给你带来80%性能损失的那20%的代码。

相关推荐

    Java JVM面试题.rar

    Java虚拟机(JVM)是Java程序运行的基础,它是一个抽象的计算机系统,负责执行Java字节码。在Java开发和面试中,JVM相关的知识是必不可少的一部分。下面,我们将深入探讨Java JVM的一些核心概念和面试常问问题。 1....

    面向对象的设计模式学习.docx

    工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪个类。这样,工厂方法将实例化操作推迟到子类中,实现了对类的封装。包括抽象工厂角色、具体工厂角色、抽象产品角色和具体产品角色四个角色。 4. **...

    java中的栈(深层了解java虚拟机对对象的内存分布)

    后者利用了字符串常量池(String Constant Pool)的概念,当字符串字面量首次出现时,会在常量池中创建一个新的字符串对象,之后相同的字符串字面量将直接引用池中的已有对象,避免了重复创建相同内容的字符串。...

    JAVA核心知识点整理.docx

    新生代是 JVM 的一块小内存区域,用于存储新创建的 JAVA 对象。 2. 幸存代: 幸存代是 JVM 的一块小内存区域,用于存储新生代中存活的 JAVA 对象。 3. 老年代: 老年代是 JVM 的一块大内存区域,用于存储长期存活的 ...

    JAVA内存分区与CC++内存分区的总结

    每当有新的对象被创建时,就会在堆上分配空间。垃圾回收机制主要针对堆区进行,自动管理对象的生命周期,释放不再使用的对象占用的空间。 2. **栈区**:每个线程都有自己独立的栈空间,用于存储局部变量、操作参数...

    代理模式

    2. 虚拟代理:在目标对象创建代价较大时,可以通过代理对象先返回一个简单的对象,待需要时再加载真实的对象,如图片预加载、大数据计算等场景。 3. 安全代理:用于控制不同用户对真实对象的访问权限,实现安全控制...

    04.GC要做的事情1

    那么这个对象将会放置到一个叫做F-Queue的队列中,并在稍后会由一个虚拟机自动创建的、低优先级的Finalizer线程去执行它,这里所谓的执行就是触发finalize方法,而不是等待这个方法结束,因为有可能方法内部执行时间...

    String、StringBuilder和StringBuffer的区别

    这意味着每次对String对象进行修改(如拼接操作),实际上都会创建一个新的String对象,这在频繁修改字符串内容时可能会导致大量的内存开销,特别是在多线程环境中,这种性能问题更加显著。例如,以下代码中,每进行...

    学习深入理解Java虚拟机的前几章笔记

    每次垃圾回收时,对象都会从Eden区或其中一个Survivor区移动到另一个Survivor区,经过几次生存周期后,幸存的对象会被提升到老年代。 - **老年代**:存放较长时间存活的对象以及大对象,如长数组等。 - **方法区**...

    深入理解Java:SimpleDateFormat安全的时间格式化

    创建一个SimpleDateFormat实例需要耗费很大的代价,包括内存和JVM空间的占用。因此,在程序中 应该尽量少的创建SimpleDateFormat实例。 知识点3: 解决SimpleDateFormat非线程安全性的方法 为了解决...

    Tomcat启动参数调优

    年轻代是堆的一个子集,主要用于存储新创建的对象。它又分为Eden区和两个Survivor区。 - **最大年轻代大小** (`-XX:MaxNewSize`): 设置年轻代的最大大小。 例如,`-XX:MaxNewSize=128m` 表示年轻代的最大大小为128...

    JAVA 多线程

    Java多线程是Java编程中一个重要的概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应速度。在理解多线程之前,我们首先需要了解基础概念:程序、进程和线程。 1. **程序**:程序是静态的代码集合,...

    垃圾回收-GC简单总结.pdf

    2. 虚拟机栈:是线程私有的,生命周期与线程相同,每个方法执行时都会创建一个栈帧,用于保存局部变量表、操作数栈、动态连接和方法返回地址等信息。栈帧随着方法的开始而入栈,方法结束而出栈。虚拟机栈可能抛出...

    jobjectpool:Java 中的通用并发对象池

    在Java中,每当创建一个新对象时,JVM都需要进行内存分配、构造函数调用等一系列操作,这在高并发场景下可能会成为性能瓶颈。而对象池通过复用已创建的对象,避免了这些开销,特别是在创建和销毁对象成本较高的情况...

    JAVA23中设计模式精讲

    单例模式是这23种设计模式之一,它的核心思想是确保一个类在整个系统中只有一个实例,并通过静态方法提供全局访问。这种模式尤其适用于那些需要频繁使用的、创建代价高昂的对象,或者需要共享状态的工具类。 单例...

    Java垃圾回收机制的学习和使用

    1. 引用计数法:每个对象有一个引用计数,每当对象被引用,计数增加,反之减少。当计数为0时,对象被视为垃圾。这种方法快速但存在缺点,如处理循环引用时的困难。 2. tracing算法:从根集(如全局变量、栈上的引用...

    垃圾回收机制学习笔记

    - 新生代主要用于存放新创建的对象,而老年代则存放经过多次垃圾回收后仍然存活的对象。 - Java堆的空间大小可以通过JVM参数进行配置。 2. **方法区**: - 方法区也称为永久代(PermGen space),用于存储已被...

    个人面试题目(java)

    - 示例代码中,`str1`和`str2`指向的是同一个字符串池中的对象,因此`str1 == str2`的结果为`true`。 - `str3`是通过`new String`的方式创建的,它不在字符串池中,即使其内容与`str2`相同,但由于它们位于不同的...

    java编码规范考试题答案.doc

    * 方法名使用类意义完整的英文描述:第一个单词的字母使用小写、剩余单词首字母大写其余字母小写的大小写混合法。 * 方法中,存取属性的方法采用setter和getter方法,动作方法采用动词和动宾结构。 * 常量名使用全...

Global site tag (gtag.js) - Google Analytics