所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size.这是两个在平时不太常见的名词,本文会对这两个名词做一个详细的解释。
Shallow Size对象自身占用的内存大小,不包括它引用的对象。针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。针对数组类型的对象,它的大小是数组元素对象的大小总和。
Retained SizeRetained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。
看图理解Retained Size上图中,GC Roots直接引用了A和B两个对象。
A对象的Retained ...
你得先知道在介绍双亲委派机制的时候,不得不提ClassLoader(类加载器)。说ClassLoader之前,我们得先了解下Java的基本知识。 Java是运行在Java的虚拟机(JVM)中的,但是它是如何运行在JVM中了呢?我们在IDE中编写的Java源代码被编译器编译成**.class**的字节码文件。然后由我们得ClassLoader负责将这些class文件给加载到JVM中去执行。 JVM中提供了三层的ClassLoader:
Bootstrap classLoader:主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。
ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。
AppClassLoader:主要负责加载应用程序的主函数类
那如果有一个我们写的Hello.java编译成的Hello.class文件,它是如何被加载到JVM中的呢?别着急,请继续往下看。
双亲委派机制我打开了我的AndroidStudio,搜索了下“ClassLoade ...
我那会就是想着足月就能生出来,每次B超胎儿也总是比实际孕周大两周,盼望着盼望着终于到了B超测的孕37周,双顶径9.1,估重3620左右,胎儿偏大,也做好了随时待产的准备。
就产检的各种指标,在我看来是怎么不会等到预产期的,再加上据其他人的经验,男孩容易提前出来。但是事与愿违,37周没有出来,后来盼到实际孕周的37周,还是没有发动。自我安慰说,只要躲过处女座,哪天出来都可以,但是心里还是希望能早一天卸货就早一天,也担心胎儿过大,到时候顺转剖,简直受罪。往后的日子真是数着过,觉得即漫长又短促。
就这样熬到了38周,尽管天天坚持1万多步的遛弯,最多的时候能走2万1千多步。熬过了39周,除了遛弯,我看做蹲起也有利于孩子早日发动,就这样遛弯配合蹲起。最终,过了预产期,还稳稳不动,我就有点坐不住了,2天就往医院跑一次,希望医生把我留下,可是医生说,你这各项指标都正常,我没有办法给你开住院单子,你就回去吧,只要疼了就来,如果没有发动,就下周再来,满41周我就给你开住院了。在40周+6的时候,半夜十二点半羊水破了,我知道这是要生了,立马赶往医院。预产期10月12号,到17号才出来,不仅熬过了处女座, ...
简述
默认情况下,ES集群节点都是混合节点,即在elasticsearch.yml中默认node.master: true和node.data: true。
当ES集群规模达到一定程度以后,就需要注意对集群节点进行角色划分。
ES集群节点可以划分为三种:主节点、数据节点和客户端节点。
这是一种分而治之的思想,也是一种术业专攻的体现。
三类节点说明
master - 主节点:
elasticsearch.yml :
123node.master: truenode.data: false
主要功能:维护元数据,管理集群节点状态;不负责数据写入和查询。
配置要点:内存可以相对小一些,但是机器一定要稳定,最好是独占的机器。
data - 数据节点:
elasticsearch.yml :
123node.master: falsenode.data: true
主要功能:负责数据的写入与查询,压力大。
配置要点:大内存,最好是独占的机器。
client - 客户端节点:
elasticsearch.yml :
123node.master: falsenode.data ...
1. 前言netty自行封装了FastThreadLocal以替换jdk提供的ThreadLocal,结合封装的FastThreadLocalThread,在多线程环境下的变量提高了ThreadLocal对象的查询以及更新效率.下文,将通过对比ThreadLocal与FastThreadLocal,通过源码解析,探究FastThreadLocal与FastThreadLocalThread的搭配使用后性能的奥秘.
2. ThreadLocalMapThreadLocalMap是TharedLocal中定义的静态类,其作用是保存Thared中引用的ThreadLocal对象.jdk中,每一个Thread对象中均会包含以下两个变量:
1234567891011publicclass Thread implements Runnable { // 此处省略若干代码 // 存储ThreadLocal变量,通过每个Thread存储一个ThreadLocalMap,实现了变量的线程隔离 ThreadLocal.ThreadLocalMap threadLocals = ...
Gossip算法因为Cassandra而名声大噪,Gossip看似简单,但要真正弄清楚其本质远没看起来那么容易。为了寻求Gossip的本质,下面的内容主要参考Gossip的原始论文:<>。
1. Gossip背景Gossip算法如其名,灵感来自办公室八卦,只要一个人八卦一下,在有限的时间内所有的人都会知道该八卦的信息,这种方式也与病毒传播类似,因此Gossip有众多的别名“闲话算法”、“疫情传播算法”、“病毒感染算法”、“谣言传播算法”。
但Gossip并不是一个新东西,之前的泛洪查找、路由算法都归属于这个范畴,不同的是Gossip给这类算法提供了明确的语义、具体实施方法及收敛性证明。
2. Gossip特点Gossip算法又被称为反熵(Anti-Entropy),熵是物理学上的一个概念,代表杂乱无章,而反熵就是在杂乱无章中寻求一致,这充分说明了Gossip的特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致 ...
文章导读
基本概念(相关系统调用函数,同步&异步,阻塞&非阻塞)
阻塞IO模型
非阻塞IO模型
IO多路复用模型
信号驱动IO模型
异步IO模型
Java中的BIO,NIO,AIO
一、基本概念五种IO模型包括:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO。
首先需要了解下系统调用的几个函数和基本概念。
1.1 简单介绍几个系统调用函数
由于我对于C语言不熟悉,几个系统函数参考了一些文章,如果错误欢迎指出!
recvfromLinux系统提供给用户用于接收网络IO的系统接口。从套接字上接收一个消息,可同时应用于面向连接和无连接的套接字。
如果此系统调用返回值<0,并且 errno为EWOULDBLOCK或EAGAIN(套接字已标记为非阻塞,而接收操作被阻塞或者接收超时 )时,连接正常,阻塞接收数据(这很关键,前4种IO模型都设计此系统调用)。
selectselect系统调用允许程序同时在多个底层文件描述符上,等待输入的到达或输出的完成。以数组形式存储文件描述符,64位机器默认2048个。当有数据准备好时,无法感知具体是哪个流OK了,所以需要一个一 ...
Redis 在互联网行业中使用最为广泛。Redis 在很多时候也被称为“内存数据库”,它集合了缓存和数据库的优势,但并非开启持久化和主备同步机制就可以高枕无忧。从架构设计的角度思考:缓存就是缓存,缓存数据会随时丢失,缓存存在的目的是拦截到数据库的请求,相比数据的可靠性、一致性,还是吞吐量、稳定性优先。
缓存有三大矛盾:
缓存实时性和一致性问题:当有了写入后咋办?
缓存的穿透问题:当没有读到咋办?
缓存对数据库高并发访问:都来访问数据库咋办?
第一个也就是本问题。而解决这三大矛盾的刷新策略包括:
实时策略——用户体验好,是默认应该使用的策略;
异步策略——适用于并发量大,但是数据没有那么关键的情况,好处是实时性好;
定时策略——并发量实在太大,数据量也大的情况,异步都难以满足的场景;
实时策略是最常用的策略,也是保持实时性最好的策略:
读取的过程,应用程序先从 cache 取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。如果命中,应用程序从 cache 中取数据,取到后返回。
写入的过程,把数据存到数据库中,成功后,再让缓存失效,失效后下次读取的时候,会 ...
netty
未读(0) 内存数据结构
内存分级从上到下主要分为:Arena,ChunkList,Chunk,Page,SubPage五级;
PooledArena是一块连续的内存块,为了优化并发性能在Netty内存池中存在一个由多个Arena组成的数组,在多个线程进行内存分配时会按照轮询策略选择一个Arena进行内存分配;
一个PoolArena内存块是由两个SubPagePools(用来存储零碎内存)和多个ChunkList组成,两个SubpagePools数组分别为tinySubpagePools和smallSubpagePools。每个ChunkList里包含多个Chunk按照双向链表排列,每个Chunk里包含多个Page(默认2048个),每个Page(默认大小为8k字节)由多个Subpage组成。
每个ChunkList里包含的Chunk数量会动态变化,比如当该chunk的内存利用率变化时会向其它ChunkList里移动。
123456789101112131415161718192021final PooledByteBufAllocator parent;private ...
netty
未读Netty 通过多种机制实现了高性能的内存管理,特别是在处理大量并发连接和高吞吐量的场景下。Netty 的内存管理体系主要依赖于内存池(Memory Pool)和 ByteBuf 的优化设计。以下是 Netty 实现高性能内存管理的核心机制:
1. 内存池化管理(Memory Pooling)Netty 使用了内存池(Pooled Memory Allocator)来管理内存分配。内存池化是指预先分配一块大的内存区域,将这块内存划分为多个小的内存块,供应用程序重复使用,而不是每次都从操作系统分配和释放内存。具体表现为:
减少频繁的内存分配与回收
在常规 Java 应用中,频繁分配和回收内存会导致垃圾回收(GC)压力大,影响性能。Netty 通过内存池来复用已分配的内存,避免了频繁创建和销毁对象,从而大大减轻了 GC 的负担。
Netty 的内存池会在需要时预分配大块内存,并在释放后保持已分配的内存块不被立即释放,以便快速分配下次使用。
PooledByteBufAllocator
Netty 使用 PooledByteBufAllocator 来管理内存池。它基于 jemalloc ...
