您现在的位置:赛迪网>>技术应用>>J2EE

Java理论与实践:再谈Urban性能之传言 (1)
作者:Jackie 发文时间:2005.11.15



流行问题:哪种语言的原始分配性能更快,Java 语言还是 C/C++?答案可能令人惊讶 —— 现代 JVM 中的分配比执行得最好的 malloc 实现还要快得多。HotSpot 1.4.2 之后虚拟机中的 new Object() 常见代码路径最多 10 条机器指令,而用 C 语言实现的执行得最好的 malloc 实现,每个调用平均要求的指令在 60 到 100 条之间。

而且分配性能在整体性能中不是一个微不足道的部分,测评显示:对于许多实际的 C 和 C++ 程序(例如 Perl 和 Ghostscript),整体执行时间中的 20% 到 30% 都花在 malloc 和 free 上,远远多于健康的 Java 应用程序在分配和垃圾收集上的开销。

继续,弄得一团糟

没有必要搜索众多的 blog 或 Slashdot 贴子,去寻找像“垃圾收集永远不会像直接内存管理一样有效”这样能够说服人的陈述。而且,从某个方面来说,这些话说的是对的 —— 动态内存管理并不一样快 —— 而是快得多。

malloc/free 技术一次处理一个内存块,而垃圾收集机制则采用大批量方式处理内存管理,从而形成更多的优化机会(以一些可以预见到的损失为代价)。

这条“听起来有理的意见” (以大批量清理垃圾要比一天到晚一点点儿清理垃圾更容易)得到了数据的证实。一项研究测量了在许多常见 C++ 应用程序中,用保守的 Boehm-Demers-Weiser(BDW)替换 malloc 的效果,结果是:许多程序在采用垃圾收集而不是传统的分配器运行时,表现出了速度提升。(BDW 是个保守的、不移动的垃圾收集器,严重地限制了对分配和回收进行优化的能力,也限制了改善内存位置的能力;像 JVM 中使用的那些精确的浮动收集器可以做得更好。)

在 JVM 中的分配并不总是这么快,早期 JVM 的分配和垃圾收集性能实际上很差,这当然就是 JVM 分配慢这一说法的起源。

在非常早的时候,我们看到过许多“分配慢”的意见 —— 因为就像早期 JVM 中的一切一样,它确实慢 —— 而性能顾问提供了许多避免分配的技巧,例如对象池。(公共服务声明:除了对最重量的对象之外,对象池现在对于所有对象都是严重的性能损失,而且要在不造成并发瓶颈的情况下使用对象池也很需要技巧。)但是,从 JDK 1.0 开始已经发生了许多变化;JDK 1.2 中引入的分代收集器(generational collector)支持简单得多的分配方式,可以极大地提高性能。

分代垃圾收集

分代垃圾收集器把堆分成多代;多数JVM使用两代,“年轻代”和“年老代”。对象在年轻代中分配;如果它们在一定数量的垃圾收集之后仍然存在,就被当作是”长寿的“,并晋升到年老代。

HotSpot 提供了使用三个年轻代收集器的选择(串行拷贝、并行拷贝和并行清理),它们都采用“拷贝”收集器的形式,有几个重要的公共特征。拷贝收集器把内存空间从中间分成两半,每次只使用一半。

开始时,使用中的一半构成了可用内存的一个大块;分配器满足分配请求时,返回它没有使用的空间的前 N 个字节,并把指针(分隔“使用”部分)从“自由”部分移动过来,如清单 1的伪代码所示。

当使用的那一半用满时,垃圾收集器把所有活动对象(不是垃圾的那些对象)拷贝到另一半的底部(把堆压缩成连续的),然后从另一半开始分配。 清单 1. 在存在拷贝收集器的情况下,分配器的行为

void *malloc(int n)
{
    if (heapTop - heapStart < n)
        doGarbageCollection();

    void *wasStart = heapStart;
    heapStart += n;
    return wasStart;
}


从这个伪代码可以看出为什么拷贝收集器可以实现这么快的分配 —— 分配新对象只是检查在堆中是否还有足够的剩余空间,如果还有,就移动指针。不需要搜索自由列表、最佳匹配、第一匹配、lookaside 列表 ,只要从堆中取出前 N 个字节,就成功了。


1 2 3 下一页>>




赛迪网推出“IT博客”,花不到一分钟就完成注册
评论】 【推荐】 【 】 【打印】 【关闭

·Linux专区· ·黑客攻防·

· 循序渐进教你LINUX之软件配置方法
· 解析Linux环境下的ReiserFS文件系统
· 制作个版本Linux启动盘的四种通行方法
· 新手入门:浅谈Linux的文件系统
· 循序渐进学习系列之Linux的软件配置
· 实战讲解防范网络钓鱼技术大全
· 穿梭于防火墙下的黑马 DBB后门程序
· ISP被要求协助清理Sober蠕虫病毒
· 2006年网络安全最大私募浮出水面
· SMTP安全手册 Sendmail服务器安全
· 新的验证技术能消灭垃圾邮件吗?
· 什么都想知道 反垃圾邮件技术完全解析
·中国信息化· ·成功案例·

· 2005年度CIO评选揭晓 关注信息化建设尖兵
· 专题策划:中国信息化盘点2005 展望2006
· 制造业基于知识管理的创新
· 信息化建设中的六类知识转移
· 看清潜在风险:科利华摘牌与教育信息化反思
· 姜奇平:信息化与后现代的统一战线

· 思科DWDM技术上海证券交易所应用案例
· 思科智能信息网络助美特斯邦威快速成长
· 思科网络在北京现代汽车公司的成功应用
· 亮剑汽车制造 打造随需而动的采购供应链
· HP Integrity为金保工程添砖加瓦
· 山东农行采用HP方案打造数据上收前置系统

本周文章排行


内容字典

IDL:是一些Java API,提供基于标准的与CORBA(Common Object Request Broker Architecture,公共请求代理人体系)的互操作性和连接。
Java Card API:符合ISO 7816-4的应用程序环境。主要用于智能卡的开发。
JRE:Java开发工具的一个子集。由想要重新分布JRE的终端用户和开发者使用。JRE包括Java虚拟机、Java核心类及支持文件。

您还可以阅读

· 播放基于Java的QuickTime流媒体系列之一
· Javascript+DOM访问XML文件中的数据实例
· 新一代的Web Service实现包——AXIS2
· 如何使用Spring更好地处理Struts动作
· 轻量级开发成功秘诀:露出水面的Spring

社区推荐

· 教您如何使用消息驱动Beans(一)
· EJB核心技术及其应用系列专题之一
· EJB最佳实践:如何做实体bean的保护
· DisplayTag在技术开发时的应用指南
· 周末巨献:有可能挑战Java优势的四种技术
· 争议话题:选择JSF不选Struts的十大理由
· 初学者入门教程:Shell编程概述(一)
· 详细讲解Quartz如何从入门到精通