`
cppmule
  • 浏览: 447407 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Erlang与java的内存架构比较

 
阅读更多

 

Erlang与java的内存架构比较

 

Erlang与java的内存架构比较

翻译自 http://www.javacodegeeks.com/2011/04/erlang-vs-java-memory-architecture.html 转载请注明出处,谢谢了

       我读了一篇非常非常有趣的文章(Jesper Wilhelmsson的一篇论文),是关于Erlang 虚拟机(Erlang VM)内存管理策略的。我相信对比一下Erlang和java的虚拟机内存管理策略,一定很有意思。

       先给从来没有听说过Erlang的同学做个简短的介绍。Erlang 是一门函数语言,通过异步消息传递(asynchronous message passing)来处理并发,使用语义拷贝(copy semantics)传递消息。即使Erlang分布在多个虚拟机上,运行在多台机器上,对程序员来说也是透明的。

       在某种意义上Erlang和java是相似的,他们都通过虚拟机来获得可移植性,都采用独立于操作系统的字节码技术,都使用垃圾回收机制来解脱程序员自己管理内存的麻烦。

       Erlang中线程的开销是非常低的。我相信在Erlang中,一个线程只需要大约512字节的内存。而java线程则需要512K字节的内存,大约是Erlang的一千倍多。对程序员来说,这意味着创建一个线程非常轻便。典型的Erlang系统中可以有上万的线程。所以Erlang不需要做线程池、executors等等,那些我们写java多线程要用到的东西。

       在我过去很少涉猎的语言中,我发现Erlang既保持了函数语言的特性,又能够做出真正的应用来。Erlang健壮的分布式错误处理非常惊艳,让编写任何一种网络服务变得相当容易。这种状态机的处理方式使web 服务在出错时,处理回滚非常自然。

       不过这篇文章不打算讨论Erlang的编程模型,这里主要想讨论Erlang虚拟机的内存管理方式。

       目前java虚拟机采用了一种被Erlang程序员称作“共享堆”的机制,虚拟机维护了一个可以被所有线程共享和使用的大堆(堆和栈什么区别)。这个堆占用了虚拟机的大部分内存。在这个大堆里,也包括了虚拟机的一些特殊数据区域,例如代码缓存和永久区。这些特殊数据区也是被所有线程共享的。

       相反的,Erlang使用一种私有堆的技术。每个线程都有一个只属于自己的小堆,里面包含了这个线程用到的所有数据以及线程栈。这个堆是在线程被创建的时候分配的。当这个线程结束了,它的私有堆内存就被虚拟机收回了。

       除了私有堆,Erlang中所有的线程都能访问两个特殊的堆,二进制堆和消息堆。二进制堆被分配了大量的数据块,以便线程线间共享数据。例如文件输入或是网络缓冲区。

       消息堆里放的是消息(messages)数据。这些消息也可以在进程间共享。线程之间传递消息的方式,是从发送线程复制一个指针到接收线程。这些消息数据就被存放在消息堆里。

       我对Erlang的内存模型印象深刻。被它比java更具扩展性的内存模型给震撼了。而且这门语言的语法和他的内存模型结合的非常漂亮。

       因为有私有堆,Erlang线程对自己的数据检查不需要采用任何形式的锁。并且私有堆也避免了破坏性的写,这样也就没有了对共享数据加锁的需求。

        最新版的Erlang又往前走了一步,采用了多个调度器(scheduler)。每个物理处理器有一个调度器可以保证更精确。而且这也消除了另一种需要检查的锁。仅当一个调度器无用了,才会用到锁,以便从其他处理器上获得一个新的调度器。

       关于java,我们仍然有很多东西要去学习。也是就说,java里还是有些好东西的,也正是因为这点,我才没有使用大型的Erlang系统。

       当Erlang线程积累了大量数据的时候,Erlang虚拟机会重新分配空间,扩大私有堆。然而,这个重新分配的算法会导致堆空间急速增长。在高负载下,我们看到Erlang虚拟机在几分钟内吃掉了16G的内存!每次发布版本都要小心的做负载测试,看看它的内存需求是否能被满足。

       Erlang虚拟机没有抑制内存增长的机制。虚拟机不断的分配内存,迫使系统不得不使用交换区(swap),直到虚拟内存被耗尽。这可能会导致用KVM控制台访问系统变得很迟钝。使我们不得不重启系统,才能够再次访问它。

       基于队列的编程模型让Erlang编程变得非常愉快,但这也是Elang系统设计上的致命缺陷。Erlang的每一个队列都是无界的。虚拟机不会抛出异常,也不会限制一个队列的消息数量。有时候会出现,一个进程可能由于bug而停止工作,或者进程消费消息的速度跟不上消息发送速度的情况。在这种情况下,Erlang还是允许这个进程的消息队列不断的增长,直到虚拟机被杀掉,或是这个机器被锁死了。

       这意味着当你在生产环境运行Erlang虚拟机时,要配备一个系统级的检测,以便在Erlang内存使用量飞涨的时候能够杀死进程。所以,运行大型Erlang应用的机器需要能被远程访问和操作(是不是意味着需要经常上去处理问题??)。

       总的来说,我认为在Erlang的工具箱里,“私有堆”是一个非常强大的工具。它避免了实时系统里的锁机制,这个意味着它将比java更具扩展性。而java的硬性限制内存的模型,则能在你的系统压力剧增,或是遭受DDOS攻击的时候保持稳定。

       有一个命令行,可以将Erlang的虚拟模型从“私有堆”改成“共享堆”。

       我喜欢Erlang和java。但他们很难进行比较,因为对开发者来说,他们的共同点很少。一般情况下,我在大多数系统里使用java。因为它有很好的工具支持,而且有大量的lib包可以使用。当我需要一个面向信息流的系统时,我会使用Erlang。这才是Erlang模型真正放光芒的时候。

 

分享到:
评论

相关推荐

    基于erlang的文件存储

    本项目“基于Erlang的文件存储”就是这样一个尝试,它利用Erlang强大的并发处理能力和分布式特性,为服务端提供稳定的基础架构,而客户端则通过Java的Swing组件提供用户友好的交互界面。以下是对该项目中涉及的技术...

    rabbitmq3.3.7 +erlang_21.0.1

    RabbitMQ是一个开源的消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol)标准,被广泛用于处理异步任务、系统间通信以及构建微服务架构。在这个压缩包中,我们拥有RabbitMQ的3.3.7版本和Erlang...

    erlang_win64_20.2.rar

    它支持多种客户端库,使得各种编程语言如Java、Python、Ruby、.NET等都能方便地与RabbitMQ交互。通过RabbitMQ,应用程序可以创建、发布和接收消息,实现异步任务处理、工作队列、事件驱动架构等高级功能。 在实际...

    Erlang环境,26.1.0.0和Erlang环境,26.1.0.0

    Erlang环境,如26.1.0.0版本,提供了运行Erlang应用程序的基础架构,包括虚拟机(BEAM)和标准库。Erlang以其强大的并发处理能力、容错机制和简洁的语法在消息队列服务器如RabbitMQ等项目中广泛应用。 在安装...

    linux下erlang22版本和rabbitmq3.7版本

    5. **兼容性增强**:与多种编程语言的客户端库有更好的兼容性,如Python、Java、Ruby等。 在CentOS 7和8上安装Erlang 22和RabbitMQ 3.7的步骤如下: 1. **安装Erlang**:首先,你需要下载提供的`erlang-22.0.7-1....

    RabbitMQ+ERLANG.zip

    Erlang的19.3版本则提供了对RabbitMQ的良好支持,包括内存管理、线程调度和网络通信等方面的优化,使得RabbitMQ能更高效地处理大量并发连接和消息处理。 RabbitMQ的核心概念包括生产者、消费者、交换器、队列和绑定...

    (64位)rabitmq3.7.4+(64位)erlang20.3

    Erlang 20.3则是与RabbitMQ 3.7.4兼容的一个Erlang版本。Erlang的版本选择对RabbitMQ的运行至关重要,因为不同的Erlang版本可能会影响RabbitMQ的功能、性能和兼容性。Erlang 20.3引入了一些新的特性和优化,例如改进...

    RabbitMQ+erlang

    在本文中,我们将深入探讨RabbitMQ与Erlang的结合以及它们如何协同工作。 ### 1. Erlang 语言特性 Erlang是一种函数式编程语言,特别适合构建高可用性和容错性的分布式系统。其主要特点包括: - **并发性**:...

    Erlang安装手册

    它拥有一个独特的运行时环境,类似于Java虚拟机(JVM),使得编译后的Erlang代码可以在任何支持该虚拟机的平台上运行而无需重新编译。这种特性极大地简化了部署过程,并提高了代码的便携性。 #### 二、Erlang的核心...

    Erlang Programming

    - **天生适合多核**:由于 Erlang 的并发模型与多核处理器的架构天然契合,因此在多核环境下,Erlang 应用程序能够轻松利用多核处理器的能力。 #### 三、Erlang 的案例研究 1. **AXD301 ATM 交换机** AXD301 是...

    RabbitMQ+ erlang32位系统.rar

    4. **内存管理**:Erlang的垃圾回收机制有助于保持RabbitMQ内存的高效利用,避免内存泄漏。 **RabbitMQ的应用场景** RabbitMQ适用于多种场景,例如: 1. **微服务通信**:在微服务架构中,RabbitMQ可以作为服务间...

    Erlang和RabbitMQ 消息队列

    1. **并发性**:Erlang的并发模型是基于轻量级进程(processes)的,这些进程之间通过消息传递进行通信,而非共享内存。这使得Erlang非常适合构建高并发、容错性强的系统。 2. **故障恢复**:Erlang的BEAM虚拟机...

    erlang和rabbitmq.zip

    在Erlang中,进程是轻量级的,每个进程都有自己的内存空间,相互之间通过消息传递进行通信,这种模型使得Erlang在处理并发和容错方面表现出色。 RabbitMQ是一个基于AMQP(Advanced Message Queuing Protocol)的...

    rabbitmq-server-3.7.13.exe和erlang-otp_win64_20.3.exe

    这个版本的Erlang OTP包含了20.3版的所有功能,提供了对Windows平台的支持,包括对多线程、网络通信和内存管理的优化。在安装后,开发者可以使用Erlang环境进行RabbitMQ服务器的部署和管理。 接下来是"rabbitmq-...

    RabbitMQ_Erlang

    7. **监控与维护**:RabbitMQ提供了一系列的监控工具,如`rabbitmqctl`命令行工具和Web管理界面,用于查看节点状态、队列长度、内存使用情况等。保持定期检查和日志分析是保证RabbitMQ稳定运行的重要环节。 8. **...

    Java框架研发思考.docx

    作者发现DDD的实体模型与Actor模型有相似之处,后者在Erlang和Scala中被实现。于是,他引入了Disruptor框架,利用其RingBuffer实现无锁通信,以提升并发性能。这一设计类似于Go语言的Channel模型,使得服务与实体间...

    唯快不破——高效定位线上Node.js应用内存泄漏.pdf

    最后,文档提到了阿里巴巴云计算有限公司的背景,说明了在云计算环境下,Node.js性能优化和内存泄漏定位问题需要在分布式系统中进行考虑,这包括了多种服务端语言和协议,比如C++、Erlang和Java等,以及它们与Node....

    java操作redis

    - **内存存储与持久化**:虽然 Redis 主要在内存中运行以确保高性能,但它也提供了多种持久化策略,如 RDB 快照和 AOF(Append Only File)日志,以防止数据丢失。 - **主从同步**:支持主从架构,可以进行数据同步...

Global site tag (gtag.js) - Google Analytics