- 博客(48)
- 资源 (6)
- 问答 (1)
- 收藏
- 关注
原创 String.intern()方法详解
在JDK1.6中,所有共享的 String 对象都存储在 PermGen(方法区) 中,PermGen 的大小是固定的并且在运行时是无法扩展的。你可以使用 -XX:MaxPermSize=N 配置来调整它的大小。到了Java7时代,字符串池的位置被调整到 heap 中了,这意味着你再也不会被固定的内存空间限制了。所有的字符串都保存在堆(heap)中同其他普通对象一样,这使得你在调优应用时仅需要调整堆
2017-05-30 22:06:03 410
原创 消息持久化
默认情况下,RabbitMQ的交换器、队列和消息都是非持久化的,重启RabbitMQ服务器后,所有东西都会消失,如果需要持久化消息,需要完成以下几个步骤:设置队列和交换器的durable属性为true在消息发布前,通过把它的“投递模式”(delivery mode)选项设置为2来把消息标记为持久化RabbitMQ确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件。
2017-05-29 20:44:06 527
原创 虚拟主机
每一个Rabbit都可以创建虚拟消息服务器(vhost),每一个都有自己的交换器、绑定和队列,vhost之于Rabbit服务器就像虚拟机之于物理服务器。它既能将Rabbit的众多客户区分开,又可以避免交换器和队列的命名冲突。 连接Rabbit时必须指定vhost,默认vhost是“/”,缺省用户名和密码都是guest。 当在Rabbit创建一个用户时,用户通常被指派给至少一个vhost,
2017-05-29 20:19:41 367
原创 消息通信
生产者和消费者 生产者(producer)创建消息,然后发送到代理服务器(RabbitMQ)。消息包含两部分:有效载荷(payload)和标签(label)。有效载荷是你想要传输的数据,可以是任何内容,比如图片、json等,标签描述了有效载荷,用于确定消费者。 消费者(consumer)订阅队列,RabbitMQ会把消息发给订阅队列的消费者,消费者只会收到有限载荷。 信道 客户端
2017-05-29 16:17:03 558
原创 RabbitMQ简述
RabbitMQ是用Erlang实现的一个高并发高可靠AMQP(高级消息队列协议)消息队列服务器,使用Mnesia数据库存储服务器信息,比如队列元数据、虚拟主机等使用RabbitMQ 1.安装Erlang 2.获取RabbitMQ安装包并解压 3.创建日志文件夹和Mnesia数据库文件夹 4.运行RabbitMQ sbin/rabbitmq-server 5.查看rabbitmq运行状态
2017-05-29 16:12:05 358
原创 调用方法
方法调用 方法调用是指确定被调用方法的版本(即调用哪一个方法),而不是具体方法里面代码的执行。 Java程序编译后生成的是Class文件,Class文件的编译过程并不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都是符号引用,而不是方法在实际运行时内存布局中的入口地址。这也使得Java的方法调用过程变得相对复杂起来,有些方法在类加载过程的解析阶段被确定,有些甚至要等到实际运
2017-05-29 10:50:39 1148
原创 运行时栈帧结构
概述 栈帧用于支持虚拟机进行方法调用和方法执行的数据结构,是虚拟机栈的栈元素,存储了方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。 在编译代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈都已经操作数栈都已经完全确定,并且写入到方法表的Code属性之中,因此一个栈帧需要分配多少内存,不会受
2017-05-28 21:39:53 1130
原创 类加载器
概述 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类,实现这个动作的代码模块称为“类加载器”。 对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟中的唯一性。说通俗一些,比较两个类是否“相等”,只有在两个类是由同一个类加载器的前提之下才有意义,否则,即
2017-05-28 21:28:20 203
原创 类的加载过程
概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们开始的顺序如下图所示: 解析阶段在某些情况下可以在初始化阶段之后再开始。初始化的发生时间 虚拟机规范没有规定什么情况下进行加载过程,但规定了有且只有5种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始):遇到new、gets
2017-05-28 13:16:34 389
原创 属性表集合
属性表(attribute_info)在前面的讲解之中已经出现过数次,在Class文件、字段表、方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。 虚拟机规范定义的属性 Code属性 Java程序方法体中的代码经过Javac编译器处理后,最终变为字节码指令存储在Code属性内。Code属性出现在方法表的属性集合之中,但并非所有的方法表都必须存在这个属性,譬如接
2017-05-28 12:47:11 4647 1
原创 class文件常量池
常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count) 常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References) 字面量比较接近于Java语言层面的常量概念,如文本字符串、声明为final的常量值等 符号引用则属于编译原理方面的概念,包括了下面三类常量: 1、类和接口的全限定名
2017-05-28 12:15:53 358
原创 class文件结构
概述 Java虚拟机实现了语言无关性的关键在它不和包括Java在内的任何语言绑定,它只与“class文件”这种特定的二进制文件格式关联,Class文件中包括了Java虚拟机指令集和符号表以及其他辅助信息,编程语言语言只要实现自身的编译器,将源码编译成class文件,即可以在JVM上运行。时至今日,商业机构和开源机构已经在Java语言之外发展出了一大批在Java虚拟机之上运行的语言,如Clojure
2017-05-28 11:27:02 239
原创 JDK工具
JDK命令行工具jps:虚拟机进程状况工具 用于列出正在运行的虚拟机进程,并显示虚拟机执行主类(main函数所在类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID),对于本地虚拟机进程来说,LVMID与操作系统的进程ID是一致的。 格式:jps [ options ] [ hostid ]jstat:虚拟机统计信息 用于显
2017-05-10 11:12:27 262
原创 内存分配与回收策略
优先在Eden区分配 大多数情况下,对象优先在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。 -XX:PrintGCDetails:打印内存回收日志 -XX:SurvivorRatio=8:Eden区和Survivor区的空间比例是8:1 大对象直接进入老年代 虚拟机提供了一个-XX:PretenureSizeThresh
2017-05-06 13:17:52 482
原创 垃圾收集器
收集器概览 上面一个区域是新生代收集器,下面一个区域是老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。Serial收集器 采用复制算法,单线程,在垃圾收集时必须暂停其他所有的工作线程,直到收集结束。适用于小型client应用,如桌面应用。下图为Serial和Serial Old收集器搭配使用。 ParNew收集器 采用复制算法,是Serial收集器的多线程版本。适用
2017-05-06 12:54:07 247
原创 垃圾收集算法
标记-清除算法 缺点:会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配大对象时,无法找到足够的连续内存而不得不提前出发一次垃圾收集动作。复制算法 将内存划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉。 缺点:内存缩小了一半 改进:不按照1:1的比例来划分内存空间,而是
2017-05-06 12:44:06 204
原创 确定可回收内存
垃圾回收关注的是堆和方法区两个区域。可达性分析算法以“GC Roots”对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连,则此对象是不可用的。 可做为GC Roots的对象包括以下几种:虚拟机栈(栈帧中的本地变量表)中引用的对象本地方法栈中JNI(native方法)引用的对象方法区中类静态属性引用的对象方法区中常量引用的对象
2017-05-06 12:36:16 261
原创 安装Eclipse Memory Analyzer
1、在官网下载压缩包:http://www.eclipse.org/mat/ 2、将压缩包解压到Eclipse的dropins目录下 3、重启Eclipse
2017-05-06 12:29:03 215
原创 对象的访问定位
1、使用句柄 优点:当对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要修改2、使用直接指针(HotSpot使用这种方式) 优点:速度更快,节省了一次指针定位的时间开销
2017-05-06 12:28:48 174
原创 对象内存布局
1、对象头(Header)Mark Word:存储对象自身的运行时数据,如果哈希吗、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据在32位和64位虚拟机中(未开启压缩指针)分别是32bit和64bit类型指针:执行类元数据的指针,虚拟机通过这个指针确定这个对象是哪个类的实例。数组长度:如果对象是一个Java数组,用于记录数组长度的数据。因为虚拟机可以通过普通Ja
2017-05-06 12:26:08 245
原创 普通对象(不包括数组对象、Class对象)的创建
加载类:当执行new语句时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过,如果没有,那必须先执行相应类的加载过程。分配内存(每个对象占用的内存都是连续的):对象所需内存大小在类加载完成后便可完全确定。根据Java堆中的内存是否规整(用过的内存都放在一边,空闲的内存放在另一边),分两种分配方式: 指针碰撞(Bump th
2017-05-06 12:18:34 846
原创 虚拟机内存结构概述
每一个线程都有一个程序计数器(Program Counter Register),如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是native方法,这个计数器的值则为空 虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它描述了java方法执行的内存模型:每个方法在执行时会创建一个栈帧(Stack Frame)
2017-05-06 12:14:34 1773
原创 Spring 事务 rollbackFor属性
默认情况下,在遇到运行时异常和Error,Spring事务会进行回滚,而遇到非运行时异常Exception则不会回滚 可以通过rollbackFor指定需要回滚的受检查异常,指定异常之后,被指定的异常和该异常的子类都会得到回滚,并且运行时异常和Error异常仍然会得到回滚
2017-04-25 15:20:30 7095
原创 线程池基础类_ThreadPoolExecutor (JDK1.8)
ThreadPoolExecutor简介 ThreadPoolExecutor使用线程池执行提交的任务,还维护一些基本统计信息,例如已完成任务的数量。 为了适应大多数场景,该方法提供了许多可调参数和钩子方法。但是推荐使用 Executors工厂方法构造实例:Executors.newCachedThreadPool(无限制线程池,具有自动线程回收),Executors.newFixedTh
2017-04-22 16:31:37 2409
原创 线程池基础类_ExecutorService(JDK1.8)
Executor接口public interface Executor { /** * 在未来某个时刻执行给定的任务 */ void execute(Runnable command);}ExecutorService接口作用: 1. 执行任务Runnable(execute方法) 2. 提交任务Runnable、Callable(submit方法)
2017-04-18 07:20:16 3064
原创 线程池基础类_CompletionService(JDK1.8)
CompletionService 用于解耦产生异步任务和消费任务结果,生产者提交用于执行的任务,消费者按照结果产生顺序进行消费。 通常,CompletionService需要依赖Executor去执行任务,在这种情况下,CompletionService只负责管理内部的完成队列,ExecutorCompletionService提供了这种方法的实现。public interface Com
2017-04-14 21:21:11 514
原创 线程池基础类_FutureTask(JDK1.8)
Futurepublic interface Future<V> { /** * Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, has already been cancelled, * or could
2017-04-08 08:28:14 1899
原创 Exchanger
Exchanger可以用于让两个线程执行到某一个同步点时执行数据交换,到达同步点的线程需要调用exchange()方法,先到达同步点的线程会一直等待另一个线程也到达同步点并执行exchange().。 具体可参考:http://ifeve.com/concurrency-exchanger/
2017-04-07 07:52:10 311
原创 Semaphore
Semaphore用于控制同时访问同一资源的最多线程数量。 具体可参考:http://ifeve.com/concurrency-semaphore/
2017-04-07 07:47:18 244
原创 CyclicBarrier
CountDownLatch可以实现多个线程等待另外多个线程。CyclicBarrier则是实现了多个线程之间互相等待。 具体可参考:http://ifeve.com/concurrency-cyclicbarrier/
2017-04-07 07:36:36 343
原创 CountDownLatch
http://ifeve.com/talk-concurrency-countdownlatch/实现原理CountDownLatch内部实现了一个AQS的实例Sync,CountDownLatch的初始化容量为state状态值,调用countdown时,会转而调用sync.releaseShared(1),state状态减一,而调用await()时,则转而调用sync.acquireSharedI
2017-04-07 07:25:40 258
原创 原子操作类
概述 在Atomic包里一共有13个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。Atomic包里的类基本都是使用Unsafe实现的包装类。 万变不离其宗,JDK提供的原子更新类和方法虽多,但最终依赖的都是CAS操作。原子更新基本类型类 用于通过原子的方式更新基本类型,Atomic包提供了以下三个类: 1. AtomicBoolean:原子更新
2017-04-06 21:22:25 422
原创 阻塞队列
对比“非阻塞队列” 相对于ConcurrentLinkedQueue这种非阻塞队列而言,阻塞队列提供了阻塞机制,即在队列不可用时(队满无法入队,队空无法出队),对线程进行阻塞,直至队列可用时再唤醒线程。在队列不可用时,各种处理方法如下图。 ConcurrentLinkedQueue提供了抛出异常和返回特殊值两种出入队方法,阻塞队列则另外提供了后面两种。需要注意的是,如果是无界阻塞队列
2017-04-04 10:46:47 645
原创 ConcurrentLinkedQueue
//以下代码摘自jdk1.8/** * 使用一个空节点初始化队列 */public ConcurrentLinkedQueue() { head = tail = new Node<E>(null);}/** * 在该队列的尾部插入指定的元素。 由于队列是无界限,此方法永远不会返回false。 */public boolean offer(E e) {
2017-03-26 21:26:51 309
原创 ConcurrentHashMap
并发容器之ConcurrentHashMap http://www.cnblogs.com/dolphin0520/p/3932905.htmlget方法为何不需要同步? http://blog.csdn.net/seapeak007/article/details/53409618
2017-03-26 16:44:28 219
转载 HashTable
HashMap和Hashtable的区别HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),
2017-03-23 07:28:30 276
转载 Java HashMap的死循环
http://blog.csdn.net/xiaohui127/article/details/11928865
2017-03-23 06:57:17 231
Elasticsearch大数据搜索引擎
2018-05-07
京东基础架构建设之路 全彩, 带目录版
2018-05-03
关于Java接口嵌套的应用
2013-11-04
TA创建的收藏夹 TA关注的收藏夹
TA关注的人