erlang 架构原理_Erlang与Java内存架构

erlang 架构原理

我读了一篇关于Erlang VM的内存管理策略的非常非常有趣的文章。 它是Jesper Wilhelmsson撰写的论文 ,我认为讨论Erlang的内存设置和Oracle的Java VM之间的差异可能会很好。

作为对从未听说过Erlang的人们的一个简短的介绍; 它是一种功能语言,使用异步消息传递作为并发的基础。 消息传递使用复制语义,从而可以在不止一台机器上运行的多个Erlang VM上进行分发,这实际上对程序员是透明的。

从某种意义上来说, Erlang和Java都是相似的,它们都使用虚拟机将硬件抽象为可移植层。 两种语言都使用与机器无关的字节码。 两种运行时系统都依赖垃圾回收来释放程序员进行内存管理的能力。

Erlang中的线程开销非常低。 我相信, Erlang中线程的内存要求约为512字节。 在Java中,线程通常需要大约512 KB,大约是1000倍。 对于程序员而言,结果是不必创建线程来异步执行某些工作,而不必坐下来思考。 典型的Erlang系统具有成千上万的线程。 像我们在Java中那样,线程池和执行器没有麻烦。

从我所涉猎的内容来看,我发现Erlang在功能性语言和允许您编写实际应用程序的语言之间达成了令人愉快的折衷。 (我知道我会为此感到迟疑)强大的分布式错误处理令人惊喜,编写任何类型的网络服务器实际上都很容易。 Web服务器的状态机方法使回滚错误变得完全自然。

但是这篇文章与Erlang的编程模型无关。 这是关于Erlang VM处理内存的方式。

当前的Java虚拟机使用Erlang程序员称为共享堆拓扑的东西。 所有线程都使用一个大堆。 大多数内存分配在该堆上。 除了堆之外,JVM还使用一些专用数据区域,例如代码缓存和永久生成。 这些也在所有线程之间共享。

相比之下, Erlang使用私有堆拓扑。 每个线程都有自己的微小堆,该堆包含该线程使用的所有数据以及该线程的堆栈。 线程的所有数据都在该本地堆上。 创建线程时保留它。 当线程死亡时,整个堆将简单地返回到空闲内存池。

除了专用堆之外,所有线程都共享对所谓的二进制堆和消息堆的访问。 这些是专门的堆。 二进制堆用于分配大块的任意数据,这些数据很可能在线程之间共享。 例如文件输入或网络缓冲区。

消息堆是消息中使用的数据的堆。 消息也在进程之间共享。 通过将指针从发送线程复制到接收线程,可以在线程之间传递消息。 消息的数据存储在消息堆上。

Erlang内存模型给我留下了深刻的印象。 它比Java的单堆模型具有更大的可扩展性。 语言语义和内存模型完美匹配。

例如; 堆是线程专有的简单事实使线程可以对自己的数据进行各种形式的锁检查。 再加上没有破坏性写入的事实,突然间也不需要对共享数据进行锁定检查。

最新版本的Erlang VM通过拥有多个调度程序,进一步迈出了又一步。 确切地说,每个物理处理器一个调度程序。 这消除了另一类要检查的锁。 仅在无聊的调度程序时,它才需要出去,收集锁并从另一个调度程序中获取一些进程。

在Java中,我们还有很多东西要学习。 就是说,我们在Java中有一些不错的东西,我错过了使用大型Erlang系统的情况。

当线程累积大量数据时, Erlang VM将重新分配并增加堆。 但是,重新分配算法导致堆大小快速增长。 在高负载下,我们已经看到Erlang VM在几分钟之内吞噬了16GB的RAM。 每个发行版都必须经过仔细的负载测试,以查看其内存需求是否仍然合理。

Erlang VM中没有任何机制可以抑制内存的增长。 VM会愉快地分配过多的内存,以至于系统需要进行交换,或者虚拟内存已用完。 这些可能会导致机器甚至无法响应KVM控制台访问。 过去,我们必须对机器重新通电才能重新访问它们。

基于队列的编程模型使Erlang为其编写代码变得非常有趣,这也是生产中的致命弱点。 Erlang中的每个队列都是无界的。 VM不会引发异常或限制队列中的消息数。 有时,进程会由于错误而停止处理,或者进程无法跟上发送给它的消息流的速度。 在这种情况下, Erlang将只允许该进程的队列增加,直到VM被杀死或计算机被锁定(以先到者为准)。

这意味着,当您在生产环境中运行大型Erlang VM时,您需要进行OS级别的检查,如果内存使用过多的话,这些检查将杀死进程。 对于运行大型Erlang VM的计算机,必须具有计算机的远程控制权或远程访问卡。

总之,对于每天的性能,我相信私有堆内存模型是Erlang盒子中非常强大的工具。 它将所有类型的锁定机制都排除在运行时系统之外,这意味着在相同的目的下,它将比Java更好地扩展。 当系统被洪水或DDoSed攻击时,Java对内存的严格限制将节省您的培根。

最后的想法

Erlang的VM有一个命令行开关,可以将其从使用私有堆拓扑切换到使用共享堆拓扑。

我喜欢Erlang和Java。 它们之所以难以比较,是因为它们与开发人员的共同点很少。 通常,我会在大多数系统上使用Java。 工具支持更好,可用库的数量惊人。 如果我有一个面向流的消息传递系统,我会选择Erlang 。 那时, Erlang编程模型才真正发光。

参考文献:

编码愉快! 不要忘记分享!

拜伦

相关文章:


翻译自: https://www.javacodegeeks.com/2011/04/erlang-vs-java-memory-architecture.html

erlang 架构原理

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ和RocketMQ是两个常用的消息中间件系统,它们在设计和功能上有一些区别。 1. 设计架构:RabbitMQ是基于AMQP(高级消息队列协议)设计的,而RocketMQ则是基于自定义的分布式消息中间件协议设计的。RabbitMQ使用Erlang语言开发,具有强大的可靠性和并发性能。RocketMQ则是由阿里巴巴开发,采用Java语言编写,注重高吞吐量和可扩展性。 2. 消息持久化:RabbitMQ支持消息的持久化存储,可以将消息保存在磁盘上,以防止消息丢失。RocketMQ也支持消息的持久化,但默认情况下只将消息保存在内存中,需要手动配置才能实现磁盘存储。 3. 消费模式:RabbitMQ支持多种消费模式,包括点对点和发布/订阅模式。RocketMQ支持广播和集群模式,可以实现消息的全量消费和部分消费。 4. 扩展性和可靠性:由于RabbitMQ是使用Erlang开发的,它具有良好的可靠性和可扩展性。RocketMQ则通过分布式架构和水平扩展来实现高吞吐量和可靠性。 5. 社区支持和生态系统:RabbitMQ具有活跃的社区支持和丰富的插件生态系统,可以方便地集成到各种应用中。RocketMQ虽然相对较新,但也有一定的社区支持和丰富的阿里巴巴生态系统。 综上所述,RabbitMQ和RocketMQ在设计理念、功能特性和生态系统上存在一些差异。选择使用哪个消息中间件取决于具体的应用需求和技术栈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值