SHuai's journal

the records of life and work


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 站点地图

  • 搜索

jvm 自动内存管理机制

发表于 2019-01-15 | 更新于 2019-01-24 | 分类于 计算机软件

运行时数据区域

运行时数据区域包括 方法区(Method Area)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)、堆(Heap)、程序计数器(Program Counter Register)

程序计数器

线程私有
较小的内存空间,可看作当前线程所执行的字节码的行号指示器。
如果线程正在执行Java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是Native方法则这个计数器值为空(undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈

线程私有
生命周期与线程相同,每个方法在执行的同事会创建一个栈帧(Stack Frame)用于储存局部变量表、操作数栈、动态链接、方法出口等信息。
局部变量表存放了编译期可知的各种基本数据类型(boolean, byte, char, short, int, float, long, double)、对象引用(Reference)类型和ReturnAddress类型(指向了一条字节码指令的地址)。
StackOverflowError OutOfMemoryError

本地方法栈

线程私有
与Java虚拟机栈很相似,一个执行Java方法服务,另一个执行本地方法服务。

Java堆

线程共享
一般来说是内存最大的一块。此内存区域的唯一目的是存放对象实例。(几乎所有的对象实例)JIT(Just-In-Time)编译器–即时编译器有些微妙。
Java堆又是也称作GC堆,是垃圾收集器管理的主要区域。线程共享的Java堆可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB),储存的仍然是对象实例。

方法区

线程共享
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
运行时常量池(Runtime Constant Pool) 是方法区的一部分。常量池(Constant Pool Table)用于存储编译期生成的各种字面量和符号引用。相对于 Class文件常量池 具备动态性 – String的Intern()方法。

直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分。
JDK1.4的NIO(new input/output)引入一种基于通道(Chanel)与缓冲区(Buffer)的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个储存在Java堆忠的DirectByteBuffer对象作为这块内存的引用进行操作。

hotspot虚拟机对象

类加载的时机

生命周期:加载Loading、(验证Verification、准备Preparation、解析Resolution)=(连接Linking)、初始化Initialization、使用Using、卸载Unloading

验证的主要目的是保证加载进来的Class文件的字节流包含的信息符合虚拟机的当前的要求,不会有危害自身的数据存在。
准备阶段主要是类变量进行分配内存和数据的初始化阶段。
解析是将常量池中的符号引用转化为直接引用的过程。
符号引用:符号引用是以一组符号来描述所引用的目标,符号可以是任何的字面形式的字面量,只要不会出现冲突能够定位到就行。布局和内存无关。
直接引用:是指向目标的指针,偏移量或者能够直接定位的句柄。该引用是和内存中的而布局有关的,并且一定加载进来的。

初始化阶段虚拟机规范严格规定有且只有5种情况必须立即对类初始化:

  1. 遇到new, getstatic, putstatic, invokestatic字节码指令
  2. reflect反射调用
  3. 初始化一个类,先触发初始化其父类
  4. 虚拟机启动时,指定一个要执行的主类(包含main函数),初始化这个主类
  5. JDK 1.7的动态语言支持,java.lang.invoke.MethodHandle

new:使用new关键字实例化对象。
getstatic:读引用一个类的静态字段。
putstatic:写引用一个类的静态字段。
invokestatic:调用一个类的静态方法。

OutOfMemoryError异常

数据库范式

发表于 2019-01-09 | 分类于 计算机软件

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

NF = Normal Form

第一范式(1NF)

在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。
在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。
(列不重复)

第二范式(2NF)

要求数据库表中的每个实例或记录必须可以被唯一地区分。要求实体的属性完全依赖于主关键字,不能存在仅依赖主关键字一部分的属性。如果存在仅依赖主关键字一部分的属性,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。
(行不重复)

第三范式(3NF)

A relation schema R is in third normal form with respect to a set $F$ of functional dependencies if, for all dependencies in $F^+$ of form $\alpha \to \beta$, where $\alpha \subseteq R$ and $\beta \subseteq R$, at least one of the following holds:

  • $\alpha \to \beta$ is a trivial functional dependency(that is, $\beta \subseteq \alpha$).
  • $\alpha$ is a superkey for schema R.
  • Each attribute A in $\beta - \alpha$ is contained in a candidate key for R.

A may be contained in different candidate key.

所有数据元素不但要能惟一地被主关键字所标识,而且它们之间还必须相互独立,不存在其他的函数关系。也就是说,对于一个满足2NF的数据结构来说,表中有可能存在某些数据元素依赖于其他非关键字数据元素的现象,必须消除。
要求一个关系中不包含已在其它关系已包含的非主关键字信息。在2NF基础上消除传递依赖。

阅读全文 »

java web 应用框架

发表于 2019-01-06 | 更新于 2019-01-23 | 分类于 计算机软件

SpringMVC vs. Struts2

SpringMVC

Struts2

Apache软件基金会开源项目,基于MVC设计模式的应用程序框架
MVC模式:JSP+JavaBean=Model1,JSP+Servlet+JavaBean=Model2(最典型的的MVC)

Spring

Hibernate vs. Mybatis vs. SpringDataJPA

Java Persistence API (JPA) 是一种规范。Hibernate就是实现了JPA接口的ORM(Object Relational Mapping)框架。
Spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等。Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。

Mybatis

支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

Springboot

Shiro vs. SpringSecurity

java并发

发表于 2019-01-05 | 分类于 计算机软件

Reentrancy(重进入)

重进入意味着锁的请求是基于线程(per-thread)而不是调用(invocation)
每个锁关联一个请求计数(acquisition count)和一个占有它的线程

并发容器

同步容器类包括Vector和Hashtable
并发容器改进了同步容器类,提供不会抛出ConcurrentModificationException的迭代器

ConcurrentHashMap

ConcurrentHashMap代替同步的HashMap,是常用的并发容器。
原来用公共锁同步每一个方法,并严格限制只有一个线程能同时访问容器。ConcurrentHashMap使用更加细化的分离锁机制。

  1. 任意数量读程序可以访问
  2. 读写可以并发访问
  3. 有限的写程序可以并发

ConcurrentMap

ConcurrentHashMap不能够在独占访问中被加锁。使用ConcurrentMap接口常见的复合操作:put-if-absent, remove-if-equal, replace-if-equal等都已经实现为原子操作

CopyOnWriteArrayList

同步List的一个并发替代品(CopyOnWriteArraySet是同步Set的一个并发替代品)
访问不需要同步,每次修改都会创建并重新发布一个新的容器拷贝

BlockingQueue

提供可阻塞的put和take方法,与可定时的offer和poll等价
offer方法如果未执行成功会返回一个失败状态,可以根据状态来制定策略

  1. LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列(与LinkedList和ArrayList相似)

  2. PriorityBlockingQueue优先级队列,可以使用Comparable和Comparator处理顺序

  3. SynchronousQueue没有存储能力,除非另一个线程已经准备好参与移交工作,否则put和take会一直阻塞

JVM调优

发表于 2019-01-04 | 更新于 2019-01-18 | 分类于 计算机软件

概念

回收算法

调优总结(三)-基本垃圾回收算法

  1. 按照基本回收策略分:引用计数(Reference Counting)、标记-清除(Mark-Sweep)、复制(Copying)、标记-整理(Mark-Compact)
  2. 按分区对待的方式分:增量收集(Incremental Collecting)、分代收集(Generational Collecting)
  3. 按系统线程分:串行收集、并行收集、并发收集

分代收集(Generational Collecting)

虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(Old Generation)和持久代(Permanent Generation)。

为什么新生代内存需要有两个Survivor区
Minor GC 年轻代空间清理回收
Major GC 年老代空间清理回收(因为Major GC一般伴随着Minor GC,也可以看做触发了Full GC)
Full GC 整个堆空间的清理回收
刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块survivor space S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块survivor space S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生)。S0和Eden被清空,然后下一轮S0与S1交换角色,如此循环往复。
整个过程中,永远有一个survivor space是空的。另一个非空的survivor space无碎片。

阅读全文 »

Java Message Service

发表于 2019-01-04 | 更新于 2019-01-07 | 分类于 计算机软件

JMS && AMQP

JMS 定义了JAVA API层面的标准;在java体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差;
AMQP定义了wire-level层的协议标准;天然具有跨平台、跨语言特性。
JMS(Java Message Service)JAVA消息服务: – 基于JVM消息代理的规范。ActiveMQ、HornetMQ是JMS实现
AMQP(Advanced Message Queuing Protocol) – 高级消息队列协议,也是一个消息代理的规范,兼容JMS – RabbitMQ是AMQP的实现

RabbitMQ

基于Erlang语言实现的,开源,稳定
SpringAMQP

ActiveMQ

大数据基础

发表于 2019-01-04 | 更新于 2019-01-07 | 分类于 计算机软件

以hadoop和Spark为代表的平台上进行数据分析技术
包括实时数据处理,离线数据处理,数据分析,数据挖掘,机器算法分析预测
hadoop生态

分布式发布订阅消息系统Kafka
Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

阅读全文 »

spring MVC webflux

发表于 2019-01-04 | 更新于 2019-01-23 | 分类于 计算机软件

Web on Servlet Stack
Web on Reactive Stack
[Java] SpringMVC工作原理之一:DispatcherServlet
[Java] SpringMVC工作原理之二:HandlerMapping和HandlerAdapter
[Java] SpringMVC工作原理之三:ViewResolver
[Java] SpringMVC工作原理之四:MultipartResolver

概述

DispatcherServlet 主要用作职责调度工作,本身主要用于控制流程,主要职责如下:

1、文件上传解析,如果请求类型是 multipart 将通过 MultipartResolver 进行文件上传解析;

2、通过 HandlerMapping,将请求映射到处理器(返回一个 HandlerExecutionChain ,它包括一个处理器、多个

HandlerInterceptor 拦截器);

3、 通过 HandlerAdapter 支持多种类型的处理器(HandlerExecutionChain 中的处理器);通过 ViewResolver 解析逻辑视图名到具体视图实现;本地化解析;渲染具体的视图等;

4、如果执行过程中遇到异常将交给 HandlerExceptionResolver 来解析。

使用HandlerMapping来找到并保存url请求和处理函数间的mapping关系,通过HandlerAdapter来实际调用处理函数。

123
Tan Shuai

Tan Shuai

记录生活和工作的日志

21 日志
4 分类
18 标签
RSS
GitHub E-Mail
© 2019 Tan Shuai
由 Hexo 强力驱动 v3.6.0
|
主题 – NexT.Gemini v6.6.0