Netty 介绍(一)
1.介绍
Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目。
Netty 是一个 异步的、 基于事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络 IO 程序。
Netty 主要针对在 TCP 协议下,面向 Clients 端的高并发应用,或者 Peer-to-Peer 场景下的大量数据持续传输的应用。
Netty 本质是一个 NIO 框架,适用于服务器通讯相关的多种应用场景
要透彻理解 Netty , 需要先学习 NIO 。
2. Netty 的应用场景
互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。
典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信
Netty 作为高性能的基础通信组件,提供了 TCP/UDP 和 HTTP 协议栈,方便定制和开发私有协议 ...
Java高并发JUC
不想总结了,看的尚硅谷的课程,这个人总结的很详细,保留自己看的博客地址1.JAVA高并发(JUC)之集合不安全
2.JAVA高并发(JUC)之生产者消费者
3.JAVA高并发(JUC)多线程8锁讲解
4.JAVA高并发(JUC)创建线程的第三种方式之Callable接口
5.JAVA高并发(JUC)之ReadWriteLock(读写锁)
6.JUC高并发(JUC)之BlockingQueue 阻塞队列
7.JAVA高并发(JUC)之ThreadPool线程池api及工作原理简析
volatile关键字简述
垃圾回收器(十七)
垃圾回收器GC分类与性能指标垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的JVM来实现。
由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本。
从不同角度分析垃圾收集器,可以将GC分为不同的类型。
Java不同版本新特性
语法层面:Lambda表达式、switch、自动拆箱装箱、enum
API层面:Stream API、新的日期时间、Optional、String、集合框架
底层优化:JVM优化、GC的变化、元空间、静态域、字符串常量池位置变化
垃圾收集器分类按线程数分按线程数分(垃圾回收线程数),可以分为串行垃圾回收器和并行垃圾回收器。
串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。
在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,串行回收默认被应用在客户端的Client模式下的JVM中
在并发能力比较强的CPU上,并行回收器产生的停顿时间要短于串行回收器。
和串行回收相反,并行 ...
垃圾回收相关概念(十六)
垃圾回收相关概念System.gc()的理解在默认情况下,通过system.gc()者Runtime.getRuntime().gc() 的调用,会显式触发FullGC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。
然而system.gc() )调用附带一个免责声明,无法保证对垃圾收集器的调用。(不能确保立即生效)
JVM实现者可以通过system.gc() 调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()
代码演示是否出发GC操作
/**
* System.gc()
*/
public class SystemGCTest {
public static void main(String[] args) {
new SystemGCTest();
// 提醒JVM进行垃圾回收
System.gc();
//System.runFi ...
垃圾回收相关算法(十五)
垃圾回收相关算法标记阶段:引用计数算法在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。
那么在JVM中究竟是如何标记一个死亡对象呢?简单来说,当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡。
判断对象存活一般有两种方式:引用计数算法和可达性分析算法。
引用计数算法(Reference Counting)比较简单,对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1;当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收。
优点:实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。
缺点:它需要单独的字段存储计数器,这样的做法增加了存储空间的开销。
每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销。引用计数器有一个严重的问题,即无 ...
垃圾回收概述(十四)
垃圾回收概述概念这次我们主要关注的是黄色部分,内存的分配与回收
什么是垃圾在提到什么是垃圾之前,我们先看下面一张图
从上图我们可以很明确的知道,Java 和 C++语言的区别,就在于垃圾收集技术和内存动态分配上,C语言没有垃圾收集技术,需要我们手动的收集。
垃圾收集,不是Java语言的伴生产物。早在1960年,第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生。关于垃圾收集有三个经典问题:
哪些内存需要回收?
什么时候回收?
如何回收?
垃圾收集机制是Java的招牌能力,极大地提高了开发效率。如今,垃圾收集几乎成为现代语言的标配,即使经过如此长时间的发展,Java的垃圾收集机制仍然在不断的演进中,不同大小的设备、不同特征的应用场景,对垃圾收集提出了新的挑战,这当然也是面试的热点。
什么是垃圾?垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序的结束,被保留的空间无法被其它对象使用,甚至可能导致内存溢出。
磁盘碎片整理机械硬盘需要进行磁盘整理,同时还有坏道
大 ...
String Table(十三)
String的基本特性
String:字符串,使用一对 ”” 引起来表示
String s1 = “mogublog” ; // 字面量的定义方式
String s2 = new String(“moxi”);
string声明为final的,不可被继承
String实现了Serializable接口:表示字符串是支持序列化的。实现了Comparable接口:表示string可以比较大小
string在jdk8及以前内部定义了final char[] value用于存储字符串数据。JDK9时改为byte[]
为什么JDK9改变了结构String类的当前实现将字符存储在char数组中,每个字符使用两个字节(16位)。从许多不同的应用程序收集的数据表明,字符串是堆使用的主要组成部分,而且,大多数字符串对象只包含拉丁字符。这些字符只需要一个字节的存储空间,因此这些字符串对象的内部char数组中有一半的空间将不会使用。
我们建议改变字符串的内部表示clasš从utf - 16字符数组到字节数组+一个encoding-flag字段。新的String类将根据字符串的内容存储编码为IS ...
执行引擎(十二)
执行引擎执行引擎概述执行引擎属于JVM的下层,里面包括 解释器、及时编译器、垃圾回收器
执行引擎是Java虚拟机核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。
JVM的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM所识别的字节码指令、符号表,以及其他辅助信息。
那么,如果想要让一个Java程序运行起来,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的译者。
执行引擎的工作流程
执行引擎在执行的过程中究竟需要执行什么样的字节码指令完全依赖于PC寄存器。
每当执行完一项指令操作后,PC寄存器就会更新下一条需要被 ...
直接内存(十一)
直接内存 Direct Memory不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。
直接内存是在Java堆外的、直接向系统申请的内存区间。
来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存
通常,访问直接内存的速度会优于Java堆。即读写性能高。
因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。
Java的NIO库允许Java程序使用直接内存,用于数据缓冲区
使用下列代码,直接分配本地内存空间
int BUFFER = 1024*1024*1024; // 1GB
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
非直接缓存区和缓存区原来采用BIO的架构,我们需要从用户态切换成内核态
NIO的方式使用了缓存区的概念
存在的问题也可能导致outofMemoryError异常
由于直接内存在Java堆外,因此它的大小不会直接受限于-xmx指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。缺点
...
对象实例化内存布局与访问定位(十)
对象实例化内存布局与访问定位对象实例化面试题
对象在JVM中是怎么存储的?
对象头信息里面有哪些东西?
Java对象头有什么?
从对象创建的方式 和 步骤开始说
对象创建方式
new:最常见的方式、单例类中调用getInstance的静态类方法,XXXFactory的静态方法
Class的newInstance方法:在JDK9里面被标记为过时的方法,因为只能调用空参构造器
Constructor的newInstance(XXX):反射的方式,可以调用空参的,或者带参的构造器
使用clone():不调用任何的构造器,要求当前的类需要实现Cloneable接口中的clone接口
使用序列化:序列化一般用于Socket的网络传输
第三方库 Objenesis
创建对象的步骤判断对象对应的类是否加载、链接、初始化虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + ...