ActiveMQ集群方案2热备方案

序:ActiveMQ高性能方案的不足

那么有的读者可能会问,既然ActiveMQ的高性能方案中多个节点同时工作,在某个节点异常的情况下也不会影响其他节点的工作。这样看来,ActiveMQ的高性能方案已经避免了单点故障,那么我们为什么还需要讨论ActiveMQ的高可用方案呢?

为了回答这个问题,我们先回过头来看看ActiveMQ高性能方案的一些不足。假设如下的场景:ActiveMQ A和AcitveMQ B两个服务节点已建立了Network Bridge;并且Producer1 连接在ActiveMQ A上,按照一定周期发送消息(队列名:Queue/testC);但是当前并没有任何消费者Consumer连接在任何ActiveMQ服务节点上接收消息。整个场景如下图所示:

这里写图片描述

在发送了若干消息后,我们查看两个节点ActiveMQ服务节点的消息情况,发现ActiveMQ A并没有把队列Queue/testC中的消息同步到ActiveMQ B。原来AcitveMQ Network Bridge的工作原则是:只在服务节点间传输需要传输的消息,这样做的原因是为了尽量减少AcitveMQ集群网络中不必要的数据流量。在我们实验的这种情况下并没有任何消费者在任何ActiveMQ服务节点上监听/订阅队列Queue/testC中的消息,所以消息并不会进行同步。

那么这样的工作机制带来的问题是,当没有任何消费者在任何服务节点订阅ActiveMQ A中队列的消息时,一旦ActiveMQ A由于各种异常退出,后来的消费者就再也收不到消息,直到ActiveMQ A恢复工作。所以我们需要一种高可用方案,让某一个服务节点能够7 * 24小时的稳定提供消息服务。

ActiveMQ 热备方案

1、基于共享文件系统的热备方案

1.1、方案介绍

基于共享文件系统的热备方案可以说是ActiveMQ消息中间件中最早出现的一种热备方案。它的工作原理很简单:让若干个ActiveMQ服务节点,共享一个文件系统。当某一个ActiveMQ服务抢占到了这个文件系统的操作权限,就给文件系统的操作区域加锁;其它服务节点一旦发现这个文件系统已经被加锁(并且锁不属于本进程),就会自动进入Salve模式。

ActiveMQ早期的文件存储方案、KahaDB存储方案、LevelDB存储方案都支持这个工作模式。当某个ActiveMQ节点获取了文件系统的操作权限后,首先做的事情就是从文件系统中恢复内存索引结构:KahaDB恢复BTree结构;LevelDB恢复memTable结构。

这里写图片描述

因为本专题讲解的技术体系都是工作在Linux操作系统上,所以为多个ActiveMQ提供共享文件系统方案的第三方文件系统都必须支持POSIX协议,这样Linux操作系统才能实现远程挂载。

幸运的是,这样的第三方系统多不胜举,例如:基于网络文件存储的NFS、NAS;基于对象存储的分布式文件系统Ceph、MFS、Swift(不是ios的编程语言)、GlusterFS(高版本);以及ActiveMQ官方推荐的网络块存储方案:SAN(就是成本有点高)。

我会在我另外一个专题——“系统存储”中,和大家深入讨论这些存储方案在性能、维护、扩展性、可用性上的不同。为了讲解简单,我们以下的讲解采用NFS实现文件系统的共享。NFS技术比较成熟,在很多业务领域都有使用案例。如果您的业务生产环境还没有达到滴滴、大众点评、美团那样对文件存储性能上的要求,也可以将NFS用于生产环境。

1.2、实例参考

下面我们来演示两个ActiveMQ节点建立在NFS网络文件存储上的 Master/Salve方案。关于怎么安装NFS软件就不进行介绍了,毕竟本部分内容的核心还是消息服务中间件,不清楚NFS安装的读者可以自行百度/Google。

以下是我们演示环境中的IP位置和功能:

IP位置 作用
192.168.61.140 NFS文件服务
192.168.61.139 独立的 ActiveMQ 节点
192.168.61.138 另一个独立的 ActiveMQ 节点

1)首先为两个ActiveMQ节点挂载NFS服务:

-- 在140上设置的NFS共享路径为/usr/nfs 挂载到139和138的/mnt/mfdir/路径下
-- 139和138上记得要安装nfs-utils的客户端模块
mount 192.168.61.140:/usr/nfs /mnt/mfdir/

挂载后,可以通过df命令查询挂载在后的结果:

这里写图片描述

从上图中可以看到,192.168.61.140上提供的NFS共享目录通过mount命令挂载成为了138和139两个物理机上的本地磁盘路径。

2)然后更改138和139上ActiveMQ的主配置文件,主要目的是将使用的KahaDB/LevelDB的主路径设置为在共享文件系统的相同位置:

......
<persistenceAdapter>
    <!--
    这里使用KahaDB,工作路径设置在共享路径的kahaDB文件夹下
    138和139都设置为相同的工作路径
    -->
    <kahaDB directory="/mnt/mfdir/kahaDB"/>
</persistenceAdapter>
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3)然后同时启动138和139上的ActiveMQ服务节点。这时我们可以看到某个节点出现以下的提示信息(记得是通过console模式进行观察):

......
jvm 1    |  INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[/mnt/mfdir/kahaDB]
jvm 1    |  INFO | Database /mnt/mfdir/kahaDB/lock is locked by another server. This broker is now in slave mode waiting a lock to be acquired
......
  • 1
  • 2
  • 3
  • 4

在本文的演示环境中,出现以上提示的是工作在139上的ActiveMQ服务节点。这说明这个节点发现主工作路径已经被其他ActiveMQ服务节点锁定了,所以自动进入了Slave状态。另外这还说明,另外运行在138物理机上的ActiveMQ服务抢占到了主目录的操作权。

接下来我们将工作在138上的ActiveMQ服务节点停止工作,这时139上的ActiveMQ Slave服务节点自动切换为Master状态:

......
jvm 1    |  INFO | KahaDB is version 6
jvm 1    |  INFO | Recovering from the journal @1:47632
jvm 1    |  INFO | Recovery replayed 53 operations from the journal in 0.083 seconds.
jvm 1    |  INFO | PListStore:[/usr/apache-activemq-5.13.1/bin/linux-x86-64/../../data/activemq2/tmp_storage] started
jvm 1    |  INFO | Apache ActiveMQ 5.13.1 (activemq2, ID:vm2-46561-1461220298816-0:1) is starting
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

从以上的提示可以看到,139上的ActiveMQ节点在自己的内存区域恢复了KahaDB的索引信息,并切换为Master状态继续工作。需要注意的是,在139上的ActiveMQ节点切换为Master状态后,就算之前138上的ActiveMQ节点重新恢复工作,后者也不会再获得主目录的操作权限,只能进入Salve状态。

2、基于共享关系型数据库的热备方案

基于关系型数据库的热备方案它的工作原理实际上和基于共享文件系统的热备方案相似:

  • 首先使用关系型数据库作为ActiveMQ的持久化存储方案时,在指定的数据库中会有三张数据表:activemq_acks,activemq_lock,activemq_msgs(有的情况下您生成的数据表名会是大写的,这是因为数据库自身设置的原因);

  • 其中“activemq_lock”这张数据表记录了当前对数据库拥有操作权限的ActiveMQ服务的ID信息、Name信息。各个ActiveMQ服务节点从这张数据表识别当前哪一个节点是Master状态;

  • 当需要搭建热备方案时,两个或者更多的ActiveMQ服务节点共享同一个数据服务。首先抢占到数据库服务的ActiveMQ节点,会将数据库中“activemq_lock”数据表的Master状态标记为自己,这样其它ActiveMQ服务节点就会进入Salve状态。

之前讲述了如何进行ActiveMQ服务的数据库存储方案的配置,这里就不再进行赘述。只需要将每个ActiveMQ服务节点的数据库连接设置成相同的位置,即可完成该热备方案的配置工作。

为了便于各位读者进行这种方案的配置实践,这里给出了关键的配置信息:实际上真的很简单,一定要首先确保您的数据库是可用的,并且每一个ActiveMQ节点都这样配置:

......
<broker xmlns="http://activemq.apache.org/schema/core">
    ......
    <persistenceAdapter>
        <!-- 设置使用的数据源 -->
        <jdbcPersistenceAdapter dataSource="#mysql-ds"/>
    </persistenceAdapter>
    ......
</broker>
......

<!-- 一定要确保数据库可用,且在ActiveMQ的lib目录中有必要的jar文件 -->
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://您的mysql连接url信息?relaxAutoCommit=true"/>
    <property name="username" value="activemq"/>
    <property name="password" value="activemq"/>
    <property name="poolPreparedStatements" value="true"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3、LevelDB + Zookeeper的热备方案

从ActiveMQ V5.9.0+ 版本开始,ActiveMQ为使用者提供了一种新的Master/Salve热备方案。这个方案中,我们可以让每个节点都有自己独立的LevelDB数据库(不是像1小节那样共享LevelDB的工作目录),并且使用Zookeeper集群控制多个ActiveMQ节点的工作状态,完成Master/Salve状态的切换。工作模式如下图所示(摘自官网):

这里写图片描述

在这种新的工作模式下,Master节点和各个Salve节点通过Zookeeper进行工作状态同步,即使某个Salve节点新加入也没有问题。下面我们一起来看看如何使用LevelDB + Zookeeper的热备方案。下表中是我们将要使用的IP位置和相关位置的工作任务:

IP位置 作用
192.168.61.140 单节点状态的zookeeper服务
192.168.61.139 独立的 ActiveMQ 节点
192.168.61.138 另一个独立的 ActiveMQ 节点

在这里的演示实例中我们使用单节点的ZK工作状态(但是正式生产环境中,建议至少有三个zookeeper节点)。

1)首先更改139和138上工作的ActiveMQ服务节点,让它们使用独立的LevelDB,并且都连接到zookeeper服务。

......
<!--
注意无论是master节点还是salve节点,它们的brokerName属性都必须一致
否则activeMQ集群就算连接到了zookeeper,也不会把他们当成一个Master/Salve组
-->
<broker xmlns="http://activemq.apache.org/schema/core"  brokerName="activemq" dataDirectory="${activemq.data}">
    ......
    <persistenceAdapter>
        <replicatedLevelDB
                directory="/usr/apache-activemq-5.13.1/data/levelDB"
                replicas="1"
                bind="tcp://0.0.0.0:61615"
                zkAddress="192.168.61.140:2181"
                zkPath="/activemq/leveldb"/>
    </persistenceAdapter>
    ......
</broker>
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

我们介绍一下以上配置段落所使用的一些重要属性。通过LevelDB + Zookeeper组建的热备方案中肯定会有一个ActiveMQ节点充当Master节点,至于有多少个Salve节点就可以根据读者所在团队、项目、需求等因素来综合考虑了。这些Master节点和Salve节点的主配置文件中设置的brokerName属性必须一致,否则activeMQ集群就算连接到了zookeeper,也不会把他们当成一个Master/Salve组。

directory属性是LevelDB的基本设置,表示当前该节点使用的LevelDB所在的主工作目录,由于每个节点都有其独立运行的LevelDB,所以各个节点的directory属性设置的目录路径可以不一样。但是根据对正式环境的管理经验,建议还是将每个节点的directory属性设置成相同的目录路径,方便进行管理。

对于replicas属性,官方给出的解释如下:

The number of nodes that will exist in the cluster. At least (replicas/2)+1 nodes must be online to avoid service outage.(default:3)

这里的“number of nodes”包括了Master节点和Salve节点的总和。换句话说,如果您的集群中一共有3个ActiveMQ节点,且只允许最多有一个节点出现故障。那么这里的值可以设置为2(当然设置为3也行,因为整型计算中 3 / 2 + 1 = 2)。但如果您将replicas属性设置为4,就代表不允许3个节点的任何一个节点出错,因为:(4 / 2) + 1 = 3,也就是说3个节点是本集群能够允许的最小节点数。

一旦zookeeper发现当前集群中可工作的ActiveMQ节点数小于所谓的“At least (replicas/2)+1 nodes”,在ActiveMQ Master节点的日志中就会给出提示:“Not enough cluster members connected to elect a master.”,然后整个集群都会停止工作,直到有新的节点连入,并达到所规定的“At least (replicas/2)+1 nodes”数量。

bind属性指明了当本节点成为一个Master节点后,通过哪一个通讯位置进行和其它Salve节点的消息复制操作。注意这里配置的监听地址和端口不能在transportConnectors标签中进行重复配置,否则节点在启动时会报错。

When this node becomes a master, it will bind the configured address and port to service the replication protocol. Using dynamic ports is also supported.

zkAddress属性指明了连接的zookeeper服务节点所在的位置。在以上实例中由于我们只有一个zookeeper服务节点,所以只配置了一个位置。如果您有多个zookeeper服务节点,那么请依次配置这些zookeeper服务节点的位置,并以“,”进行分隔:

zkAddress="zoo1.example.org:2181,zoo2.example.org:2181,zoo3.example.org:2181"
  • 1

由于zookeeper服务使用树形结构描述数据信息,zkPath属性就是设置整个ActiveMQ 主/备方案集群在zookeeper存储数据信息的根路径的位置。当然这个属性有一个默认值“/default”,所以您也可以不进行设置。

  • 在完成138和139两个节点的ActiveMQ服务配置后,我们同时启动这两个节点(注意,为了观察ActiveMQ的日志请使用console模式启动)。在其中一个节点上,可能会出现以下日志信息:
......
jvm 1    |  INFO | Opening socket connection to server 192.168.61.140/192.168.61.140:2181
jvm 1    |  INFO | Socket connection established to 192.168.61.140/192.168.61.140:2181, initiating session
jvm 1    |  INFO | Session establishment complete on server 192.168.61.140/192.168.61.140:2181, sessionid = 0x1543b74a86e0002, negotiated timeout = 4000
jvm 1    |  INFO | Not enough cluster members have reported their update positions yet.
jvm 1    |  INFO | Promoted to master
jvm 1    |  INFO | Using the pure java LevelDB implementation.
jvm 1    |  INFO | Apache ActiveMQ 5.13.1 (activemq, ID:vm2-45190-1461288559820-0:1) is starting
jvm 1    |  INFO | Master started: tcp://activemq2:61615
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

  从以上的日志可以看到,这个节点连接上了zookeeper,并且分析了当前zookeeper上已连接的其它节点状态后(实际上这个时候,还没有其它节点进行连接),将自己“提升为Master”状态。在另外一个AcitveMQ的节点日志中,读者可以发现另一种形式的日志提示,类似如下:

......
jvm 1    |  INFO | Opening socket connection to server 192.168.61.140/192.168.61.140:2181
jvm 1    |  INFO | Socket connection established to 192.168.61.140/192.168.61.140:2181, initiating session
jvm 1    |  INFO | Session establishment complete on server 192.168.61.140/192.168.61.140:2181, sessionid = 0x1543b74a86e0005, negotiated timeout = 4000
jvm 1    |  INFO | Slave started
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  从日志中可以看到,这个节点成为了一个Slave状态的节点。

  • 接下来我们尝试停止当前Master节点的工作,并且观察当前Salve节点的状态变化。注意,如上文所述,replicas属性的值一定要进行正确的设置:如果当Master节点停止后,当前还处于活动状态的节点总和小于“(replicas/2)+1”,那么整个集群都会停止工作!
......
jvm 1    |  INFO | Not enough cluster members have reported their update positio ns yet.
jvm 1    |  INFO | Slave stopped
jvm 1    |  INFO | Not enough cluster members have reported their update positio ns yet.
jvm 1    |  INFO | Promoted to master
jvm 1    |  INFO | Using the pure java LevelDB implementation.
jvm 1    | Replaying recovery log: 5.364780% done (956,822/17,835,250 bytes) @ 1 03,128.23 kb/s, 0 secs remaining.
jvm 1    | Replaying recovery log: 9.159451% done (1,633,611/17,835,250 bytes) @  655.68 kb/s, 24 secs remaining.
jvm 1    | Replaying recovery log: 23.544615% done (4,199,241/17,835,250 bytes)  @ 2,257.21 kb/s, 6 secs remaining.
jvm 1    | Replaying recovery log: 89.545681% done (15,970,696/17,835,250 bytes)  @ 11,484.08 kb/s, 0 secs remaining.
jvm 1    | Replaying recovery log: 100% done
jvm 1    |  INFO | Master started: tcp://activemq1:61615
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

  从以上的日志片段可以看到,Salve节点接替了之前Master节点的工作状态,并恢复之前已同步的LevelDB文件到本节点的本地内存中,继续进行工作。

  我们在这篇文章做的演示只有两个ActiveMQ服务节点和一个Zookeeper服务节点,主要是为了向读者介绍ActiveMQ下 LevelDB + Zookeeper的高可用方案的配置和切换过程,说明ActiveMQ高可用方案的重要性。实际生产环境下,这样的节点数量配置会显得很单薄,特别是zookeeper服务节点只有一个的情况下是不能保证整个集群稳定工作的。正式环境下, 建议至少使用三个zookeeper服务节点和三个ActiveMQ服务节点,并将replicas属性设置为2。

4、ActiveMQ客户端的故障转移

以上三种热备方案,都已向各位读者介绍。细心的读者会发现一个问题,因为我们没有使用类似Keepalived那样的第三方软件支持浮动IP。那么无论以上三种热备方案的哪一种,虽然服务端可以无缝切换提供连续的服务,但是对于客户端来说连接服务器的IP都会发生变化。也就是说客户端都会因为连接异常脱离正常工作状态。

为了解决这个问题,AcitveMQ的客户端连接提供了配套的解决办法:连接故障转移。开发人员可以预先设置多个可能进行连接的IP位置(这些位置不一定同时都是可用的),ActiveMQ的客户端会从这些连接位置选择其中一个进行连接,当连接失败时自动切换到另一个位置连接。使用方式类似如下:

......
//这样的设置,即使在发送/接收消息的过程中出现问题,客户端连接也会进行自动切换
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://192.168.61.138:61616,tcp://192.168.61.139:61616)");
......
  • 1
  • 2
  • 3
  • 4

这样的连接设置下,客户端的连接就可以随服务端活动节点的切换完成相应的转换。

5、形成生产环境方案

ActiveMQ中主要的高性能、高可用方案到此就为各位读者介绍完了。可以看到在ActiveMQ单个节点性能配置已优化的前提下,ActiveMQ集群的高性能方案可能会出现节点失效消息服务停止的情况;而ActiveMQ集群的高可用性方案中,由于一次只有一个节点是Master状态可以提供消息服务外,其他Salve节点都不能提供服务,所以并不能提高整个ActiveMQ集群的性能。

因为两种方案都有其限制因素,所以在实际工作中将ActiveMQ应用到生产环境时,除非您的业务环境有特殊要求的情况,一般建议将ActiveMQ的高性能方案和高可用方案进行结合。以下向各位读者提供一种ActiveMQ高性能和高可用性结合的方案:

  • 将9个ActiveMQ节点分为三组(brokerName1、brokerName2、brokerName3),每组都有三个ActiveMQ服务节点。另外准备三个节点的zookeeper服务集群,所有三个组九个ActiveMQ服务都共享这三个zookeeper服务节点(只是每组ActiveMQ所设置的zkPath属性不一样);

  • 将每组的三个ActiveMQ服务节点做LevelDB + Zookeeper的热备方案(且设置replicas=2)。保证每组只有一个节点在一个时间内为Master状态。这样整个集群中的九个ActiveMQ服务节点就同时会有三个ActiveMQ服务节点处于Master状态;

  • 将整个集群中所有ActiveMQ服务节点的高性能方案设置为“组播发现”,并都采用一个相同的组播地址(可以采用默认的组播地址)。这样三个处于Master状态的ActiveMQ服务节点就会形成一个高性能方案(处于Salve状态的节点不会发出组播消息)。整个设计结构如下图所示:

这里写图片描述

原文地址:https://www.cnblogs.com/jobbible/p/13507444.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


jinfo 命令可以用来查看 Java 进程运行的 JVM 参数,命令如下:[root@admin ~]# jinfo --helpUsage: jinfo [option] &lt;pid&gt; (to connect to running process) jinfo [option] &lt;executable &lt;core&gt; (to connect to a core file) jinfo [option] [serve
原文链接:https://www.cnblogs.com/niejunlei/p/5987611.htmlJava Virtual Machine Stacks,线程私有,生命周期与线程相同,描述的是Java方法执行的内存模型:每一个方法执行的同时都会创建一个栈帧(Stack Frame),由于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法的执行就对应着栈帧在虚拟机栈中的入栈,出栈...
java 语言, 开发者不能直接控制程序运行内存, 对象的创建都是由类加载器一步步解析, 执行与生成与内存区域中的; 并且jvm有自己的垃圾回收器对内存区域管理, 回收; 但是我们已经可以通过一些工具来在程序运行时查看对应的jvm内存使用情况, 帮助更好的分析与优化我们的代码;jps查看系统中有哪些java进程jps 命令类似与 linux 的 ps 命令,但是它只列出系统中所有的 Java 应用程序。 通过 jps 命令可以方便地查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息
1.jvm的简单抽象模型:  2.类加载机制     双亲委派模型是为了防止jdk核心类库被篡改,如果需要打破可以重写Classloader.loadClass方法。r 双亲委派模型:一个类加载器收到一个类的加载请求,他会先判断自身是否已存在该类,如果不存在上抛给上一级类加载器ClassLoad
堆外内存JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,比如Netty,广泛使用了堆外内存,但是这部分的内存并不归JVM管理,GC算法并不会对它们进行回收,所以在使用堆外内存时,要格外小心,防止内存一直得不到释放,造成线上故障。堆外内存的申请和释放JDK的ByteBuffe
1.springboot和tomcat2.springcloud的请求如何通过网关鉴权?3.springmvc启动时组件的加载顺序?4.mybatis如何同时更新三条记录5.hibernate实现级联更新6.一个web程序应用程序启动时的加载流程7.如何向www.baidu.com地址发出请求时,并获取相应?8.???9.谈谈你对tcp/iptelnetudp协
堆设置-Xms256M:初始堆大小256M,默认为物理内存的1/64-Xmx1024M:最大堆大小1024M,默认为物理内存的1/4,等于与-XX:MaxHeapSize=64M-Xmn64M:年轻代大小为64M(JDK1.4后支持),相当于同时设置NewSize和MaxNewSize为64M-XX:NewSize=64M:初始年轻代大小-XX:MaxNewSize=256M:最大年轻代大小(默认
一.概述收集算法(JVM之垃圾回收-垃圾收集算法)是内存回收的抽象策略,垃圾收集器就是内存回收的具体实现。JVM规范对于垃圾收集器的应该如何实现没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器差别较大,这里只看HotSpot虚拟机。就像没有最好的算法一样,垃圾收集器
Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象,如下图所示: 在Java中,堆被划分成两个不同的区域:新生代(Young)、老年代(Old)。新生代(Young)又被划分为三个区域:Eden、S0、S1。 这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包
JVM深入理解JVM(4)——如何优化JavaGC「译」 PostedbyCrowonAugust21,2017本文翻译自SangminLee发表在Cubrid上的”BecomeaJavaGCExpert”系列文章的第三篇《HowtoTuneJavaGarbageCollection》,本文的作者是韩国人,写在JDK1.8发布之前,虽然有些地
 JVM深入理解JVM(2)——GC算法与内存分配策略 PostedbyCrowonAugust10,2017说起垃圾收集(GarbageCollection,GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Scala等)程序员在提升开
运行时数据区  线程独有本地方法栈、虚拟机栈、程序计数器这些与线程对应的数据区会随着线程开始和结束创建和销毁  整体公有元数据区(又称方法区)、堆区会随着虚拟机启动而创建,随着虚拟机退出而销毁 
java整个堆大小设置:Xmx和Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍。永久代PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍年轻代Xmx的设置为老年代存活对象的1-1.5倍老年代的内存大小设置为老年代存活对象的2-3倍BTW: Sun官方建议年轻代
栈顶缓存(Top-of-StackCashing)技术基于栈式架构得虚拟机所使用的零地址指令更加紧凑,但完成一项操作的时候必然使用更多的入栈和出栈指令,这同时也就意味着将需要更多的指令分派次数和内存读写次数 由于操作数是存储在内存重的,因此频繁地执行内存读/写操作必然影响速度。 综上
自用。同样的代码在不同的平台生成的机器码是不一样的,为什么java代码生成的字节码文件,能在不同的平台运行?因为不同版本的jdk里面的虚拟机会屏蔽不同操作系统在底层硬件与指令上的区别。栈:线程栈,局部变量存放栈内存区域。线程(分配一个栈)运行分配栈将局部变量放入内存。怎么放:栈
jconsole监控:1.java启动命令加上参数java-Djava.rmi.server.hostname=172.16.17.247-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port=2099-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false -XX:+Unlock
类加载器分类publicclassStackStruTest{publicstaticvoidmain(String[]args){//对用户自定义个类来说:默认使用系统类加载器进行加载-----AppClassLoaderClassLoaderclassLoader=StackStruTest.class.getClassLoader();System.out.p
堆体系结构一个JVM实例只存在一个堆内存,堆内存的大小是可调节的。类加载器读取类文件后,需要把类、方法、常量、变量放在堆内存中,保存所有引用类型的真实信息,以方便执行器指向,堆内存分为三个部分:年轻代、老年代、永久代。Java7之前,堆内存在逻辑上分为:年轻代、老年代、永久代。物
JVM深入理解JVM(5)——虚拟机类加载机制 PostedbyCrowonAugust21,2017在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。而虚拟机中,而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟机中会发生什么变化?本文将逐步解答这
保存(持久化)对象及其状态到内存或者磁盘Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在