Java/核心
文章平均质量分 87
莫言静好、
这个作者很懒,什么都没留下…
展开
-
2021-06-01 深入分析锁的基础知识
一 对象在内存中的布局? 创建一个Object对象占用多少内存?1.1 对象在内存中的布局?SHAPE \* MERGEFORMAT 我们知道,对象是放在堆中的,那么对象是怎么构成的?只包括实例数据吗?堆中的对象主要由三部分组成:对象头(object header)、实例数据(instance data)和对齐填充(padding)。SHAPE \* MERGEFORMAT SHAPE \* MERGEFORMAT 对象头:主要由三部分组成,包括m...原创 2021-06-01 08:49:09 · 219 阅读 · 0 评论 -
2021-06-01 深入分析偏向锁、轻量级锁和重量级锁
一 重量级锁1.1 什么是重量级锁?重量级是怎么体现的?第一:执行同步代码块的时候或者执行同步方法的时候,需要为锁对象创建监视器,监视器用于关联锁对象、以及锁对象的原始头信息、重入次数、竞争失败队列、竞争队列和阻塞队列等信息,所以保存的东西占用的内存量很多,尤其是线程并发量大的时候。第二:另外线程竞争失败的队列需要进入队列挂起或者线程阻塞也需要挂起,当挂起的时间到期又需要唤醒线程,等待和唤醒是属于系统调用,会涉及到CPU在用户态和内核态切换,线程太多就会频繁切换。第三:内核线程需要操作系统进原创 2021-06-01 08:28:21 · 649 阅读 · 1 评论 -
2021-06-01 深入分析锁升级流程的基础
一 对象在内存中的布局? 创建一个Object对象占用多少内存?1.1 对象在内存中的布局?我们知道,对象是放在堆中的,那么对象是怎么构成的?只包括实例数据吗?堆中的对象主要由三部分组成:对象头(object header)、实例数据(instance data)和对齐填充(padding)。对象头:主要由三部分组成,包括mark word(关于hashcode、锁或者GC分代信息的记录), class pointer(指向方法区class的指针)、数组长度。其...原创 2021-06-01 08:00:15 · 352 阅读 · 0 评论 -
JVM专题之垃圾回收器
CMS是怎么解决传统GC暂停时间过长的问题?在CMS垃圾回收时候,有多个阶段是和应用程序并发执行,即便有暂停应用线程的阶段,那都是暂停时间很短的操作。CMS如何解决不应该回收的对象被回收?那既然和应用线程并发执行,那么应用线程完全有可能修改对象的引用,可能会造成本不应该回收的对象被回收。所以我们需要一种机制,知道哪些对象的引用发生了修改,然后需要对它引用链重新跟踪,并进行标记。但是如何知道哪些对象被修改了呢?CMS引入了Card 、Card Table数据结构,以及使用写屏障技术实现了这一点。原创 2021-04-25 15:30:10 · 467 阅读 · 0 评论 -
JVM专题之分代模型:年轻代、老年代、永久代
一 什么是GC 分代我们知道GC为了方便垃圾回收,根据对象的特点对内存做了内存分代,在JDK1.8 之前主要包括新生代,老年代和永久代,在JDK1.8之后主要是新生代,老年代。方法区的实现元数据区直接分配在直接内存上的,不受JVM 管理。如图示二 GC 为什么需要分代第一:如果不分代,那么内存只有快满的时候才会进行垃圾回收,因为需要收集垃圾对象太多,所以耗费时间,会造成长时间的应用程序卡顿第二:对象的生命周期不同,生命周期比较短的对象,如果及时回收,可以提升内存利用率所以,分代.原创 2021-04-19 23:18:37 · 1392 阅读 · 0 评论 -
热加载和热部署
目录一 什么是热加载和热部署1.1 热部署(Hot Deploy)1.2 热加载(Hot Swap)二 热加载的原理是什么2.1 检测哪些文件需要重新被加载2.2 怎么加载三 热部署的原理是什么四 区别一 什么是热加载和热部署1.1 热部署(Hot Deploy)热部署针对的是容器或者是整个应用,部署了新的资源或者修改了一些代码,需要在不停机的情况下的重新加载整个应用。1.2 热加载(Hot Swap)热加载针对的是单个字节码文件,指的是重新编..原创 2021-04-19 00:39:08 · 2261 阅读 · 1 评论 -
JVM专题之类加载机制
一 类加载是什么?什么时候加载类?加载过程是怎么样的?1.1 什么是类加载类加载就是指将在硬盘上编译好的class字节码文件,加载到JVM内存中,然后对字节码文件进行链接和初始化的过程。只有加载后的字节码文件才可以被执行引擎解释和执行。1.2 类加载的时机JVM并不是启动的时候,就把全部的class字节码加载到内存,而是根据运行时候需要进行加载。比如没有加载到内存的类能够实例化吗?要访问静态类的变量或者方法,如果所在类没有被加载到内存,能访问静态变量和或者静态方法吗?第一:创建类实例的时候,肯定要原创 2021-04-19 00:25:58 · 698 阅读 · 2 评论 -
Java虚拟机专题之内存分配(读书笔记)
一 虚拟机内存分配策略1.1 对象优先在Eden区域分配1.2 大对象直接进入老年代1.3 长期存活的对象进入老年代1.4 空间分配担保1.5 动态对象年龄判定 二 对象优先在Eden区域分配假设构建4M大小的数组,通过打印GC详细日志,也可以看到是优先在Eden上分配的。publicclass EdenMemoryAllocation {原创 2017-12-19 16:31:20 · 357 阅读 · 0 评论 -
JVM之内存结构
一 Java虚拟机运行时的内存数据区域二 为什么有线程共享区和线程独占区我们知道,Java程序在JVM中运行,有的内存对象声明周期长,不随线程的释放而释放,比如堆和方法区;但是有些内存对象,就是线程私有范围的,随着线程的结束而结束,该部分使用的内存也会被释放。当然这也是系统垃圾回收的场所只发生在线程共享区域的原因。三 程序计数器程序计数器是一块较小内存空间原创 2017-12-19 16:38:11 · 386 阅读 · 0 评论 -
Java虚拟机专题之垃圾回收(读书笔记)
一 如何判断对象是垃圾对象1.1 引用计数法 (Reference Counting)在对象中添加一个引用计数器,当有其他地方引用这个对象的时候,引用计数器就加1,当引用失效的时候就-1. 当垃圾回收器检查到引用为0,就会认为是垃圾对象,进行回收。 但是有一个问题,比如对象之间循环引用,诸如A,B两个对象,都有一个属性instance, 假设A.instance = B,B.ins原创 2017-12-19 16:44:23 · 414 阅读 · 0 评论 -
Java虚拟机专题之字节码指令(读书笔记)
一 字节码与数据类型大部分的指令都包含了其操作所对应的数据类型信息。比如iload指令用于从局部变量表中加载int类型的数据到操作栈中,而fload指令加载的则是float数据类型的数据。 二 加载与存储指令主要用于将数据在栈帧的局部变量表和操作数栈之间来回传输。将局部变量表加载到操作数栈:iload,lload,fload,dload,aload(引用类型)将一个原创 2017-12-19 16:48:41 · 473 阅读 · 0 评论 -
Java虚拟机专题之类加载机制
一 类的加载阶段类加载具体做的是什么# 根据类的权限定名,获取此类的二进制流(文件或者网络等)# 将这个字节流所代表的静态存储结构转化为方法区的运行时数据# 在内存创建一个代表这个Class的对象,然后作为数据的访问入口二 类的连接阶段2.1 验证阶段验证的目的是确保加载的Class文件的字节码流的信息符合Java虚拟机规范,不会危害虚拟机的安全。包括文原创 2017-12-19 16:53:18 · 401 阅读 · 0 评论 -
Java虚拟机专题之class文件结构(读书笔记)
我们知道一个Class文件对应着一个接口或者注解的类,但是他们并不一定定义在文件里,也可以直接由类加载器生成。 Java虚拟机定义了专门的数据类型来表示class文件的内容,他们包括u1,u2,u4表示1,2,4个无符号数 一 Class文件结构在Class文件中,各个项按照严格顺序连续存放的,他们之间没有任何填充或者对齐做为分隔符。表由任意数量的可变长度的项组成,表示Cl原创 2017-12-19 16:58:48 · 444 阅读 · 0 评论 -
Java虚拟机内存溢出
一 生成内存快照我们要检测是哪里的代码出了问题,就必须要借助一些命令或者工具定位到这个问题代码行,那么通常做法是生成内存快照,那么快照应该如何生成呢?我们可以设置JVM的参数:-XX:+HeapDumpOnOutOfMemoryError这样在内存溢出的时候,就会生成内存快照。如果要测试的话,我们可以设置以下参数,将虚拟机内存调小,方便测试:-XX:+HeapDumpOnO原创 2017-12-19 17:02:24 · 522 阅读 · 0 评论 -
Java虚拟机内存的代的划分
一 Java虚拟机为什么需要分代# 如果每次都对整个堆空间进行垃圾回收,花费的时间肯定较长# 不同的对象生命周期不一样,如果每次垃圾回收这些周期的较长的也都去遍历一下,显然没有意义。所以实现分而治之的思想,采用分代,方便进行不同生命周期的对象的管理。 二 如何划分代2.1JDK1.8 之前堆内存划分成2代:新生代(Young区),老年代(Tenured区)方法区:持原创 2017-12-19 17:04:17 · 409 阅读 · 0 评论 -
Java虚拟机专题对象内存定位
一 对象在内存中的布局1.1对象的创建过程对象的创建过程可以如下图所示:1.2 什么是符号引用和直接引用,为什么需要在常量池定位到符号的引号?在类的解析阶段,把虚拟机常量池内的符号引号替换为直接引用。1.2.1 符号引用(SymbolicReferences)就是用一组符号来描述所引用的目标,符号可以是任何形式的,只要使用时能够定位到目标即可。我们知道原创 2017-12-19 17:09:13 · 525 阅读 · 0 评论 -
编程基础 之 位运算专题
一 原码、反码和补码1.1原码原码就是将10进制数,转化为2进制码,比如:8:00001000-8: 10001000最高位表示符号位。 1.2 反码反码:如果是正数,即最高位是0,则反码是原码自己;如果是负数,即最高位符号位是1,则符号位保持不变,其余位取反。比如:8的原码:000010008的反码:00001000-8的原码:10001000-8...原创 2018-09-04 12:11:12 · 615 阅读 · 0 评论 -
Java 多线程总结
第一章 原子性 可见性 有序性1.1 原子性即某个正在执行的操作不能中断,不能被分割,要么就不执行,要么就执行完毕。正如我们所知道的synchronized代码块,这块里面的东西要么就是被执行完毕,要么就不执行。还有就是我们所熟知的基本数据类型的读写,long 和 double除外,也都是原子性的。1.2 可见性当某个线程修改了共享变量的值,其他线程能够立刻得知这个修改。但原创 2017-12-08 10:14:01 · 427 阅读 · 0 评论 -
Java中的锁
一 synchronized 内置锁和Lock的比较相同点:都能够防止多线程同时访问共享资源都支持重进入锁不同点:内置锁获取锁和释放锁是隐式的,不需要程序员手动去管理锁;Lock需要显示地获取和释放锁,灵活性也更大,如果没有释放锁,可能会导致死锁。内置锁获取锁的顺序都是无序的;Lock可以构造公平锁,这样就会按照线程到来的时间先后顺序来获取锁内置锁抛出异常的时候,释放锁原创 2017-12-08 09:59:18 · 362 阅读 · 0 评论 -
JDK1.8 HashMap 深入理解
转自:http://blog.csdn.net/zdsicecoco/article/details/51775545一 什么是HashMap,HashMap的工作原理HashMap是一个基于哈希表的Map接口实现。首先先看一下,在JDK1.8的时候,HashMap数据存储jniego工作原理:当我们使用put(KEY,VALUE)存储键值对象到HashMap ,首先会对转载 2016-10-21 14:40:55 · 1125 阅读 · 0 评论 -
JDK1.7 ConcurrentHashMap
static final class Segment extends ReentrantLock implements Serializable { transient volatile int count; transient int modCount; transient int threshold; transient volatile原创 2016-10-21 15:06:23 · 737 阅读 · 0 评论 -
JDK1.8 HashSet
原理:HashSet实现了Set接口,但是内部实现却是基于HashMap的。它的原理就是添加到集合里的值或者对象都成为了HashMap的key. 而HashMap有了Key之外,值怎么办呢。HashSet默认提供了一个供所有key共享的一个Object对象PRESENT.什么意思呢?下面会分析到。也正是HashSet是基于HashMap的,那么我们知道HashMap的key允不允许重复,是原创 2016-10-21 15:59:27 · 1010 阅读 · 0 评论 -
JDK1.7 深入理解 LinkedHashMap
我们知道我们遍历HashMap的时候,并不是按照插入顺序取出的。而是按照计算的hash然后再去计算应该存放的桶的哪一个位置。即是按照桶的顺序来遍历的,如果在同一个位置,然后接着去按照链表的顺序……如果我们希望实现按照插入顺序来遍历,怎么办呢,LinkedHashMap就派上用场了。那么,LinkedHashMap具有哪些特性呢?首先:可以按照元素的添加顺序进行迭代;其次:可以根据元原创 2016-10-25 12:54:47 · 505 阅读 · 0 评论 -
JDK1.8 IdentityHashMap
首先对于这个IdentityHashMap和HashMap相比,最大的不同在于什么呢?它允许两个key,只要引用不一样,就可以存储;但是HashMap则是根据equals方法来比较值是否一样。举个例子:MapidentityMap = new IdentityHashMap();identityMap.put("key1","val1");identityMap.put原创 2016-10-26 17:23:14 · 531 阅读 · 0 评论 -
Java 并发编程阅读笔记
第一章 原子性 可见性 有序性1.1原子性即某个正在执行的操作不能中断,不能被分割,要么就不执行,要么就执行完毕。正如我们所知道的synchronized代码块,这块里面的东西要么就是被执行完毕,要么就不执行。还有就是我们所熟知的基本数据类型的读写,long 和 double除外,也都是原子性的。1.2可见性当某个线程修改了共享变量的值,其他线程能够立刻得知这个修改。但是根原创 2016-11-01 10:28:04 · 344 阅读 · 0 评论 -
Java 并发编程 基础
第一章 线程的操作1.1创建多线程的方式第一种:继承Thread第二种:实现Runnable接口1.2线程的常用方法currentThread(): 获取当前线程isAlive():判断当前线程是否处于活动状态sleep():指定毫秒数让当前线程休眠。getId():获取当前线程的Id1.3停止线程停止线程就是线程在处理任务完成之前,停掉正在进行的操作。Th原创 2016-11-01 11:04:01 · 448 阅读 · 0 评论 -
select poll epoll
一 虚拟存储器一个作业在运行之前,没有必要把全部作业装入内存,而仅将那些当前要运行的那部分页面或段,先装入内存便可以启动运行,其余部分暂时驻留磁盘程序在运行时,如果他所要访问的页面或者端已调入内存,便可以继续执行下去,但是如果程序页面和段尚未调入内存(页面缺失或缺段),此时程序要利用操作系统所提供的请求调页(段)功能,将他们调入内存,以使得进程能够继续执行下去如果此原创 2017-05-05 10:34:55 · 323 阅读 · 0 评论 -
nio demo
nio demo原创 2017-05-04 17:13:59 · 638 阅读 · 0 评论 -
Java内存模型与线程
一:什么是Java内存模型Java内存模型:是为了消除或者屏蔽各类硬件和内存访问差异,从而实现java程序在各种平台下能达到一致的内存访问效果。主要目标:定义程序中实例字段,静态字段,以及构成数组对象的元素,不包括局部变量和方法参数。因为后者是线程私有的,不会被共享,自然不存在资源竞争问题。主要的一些性质:1 Java 内存模型规定所有的共享变量都存储在主内存Main Memory原创 2017-12-04 22:23:31 · 279 阅读 · 0 评论 -
位运算
一 位运算符&与运算:被比较的两个数,最后一位都为1,结果才是1比如11&15,他们二进制是1011和 111110111111结果1011,所以是11比如128和129,他们二进制是10000000和 10000001000011011000000010000001结果=10000000所以结果是128|或运算:被比较的两个数的二进制位数只有一个是1就为1原创 2017-12-08 09:29:23 · 298 阅读 · 0 评论 -
hashCode() 和equals() 区别和作用
一 hashCode()和equals()区别和作用Java中任何一个类都具备hashcode和 equals方法,因为他们object定义的。equals用来判断对象是否相等hashcode返回一个int类型的数,即哈希值,一般作用是用于将数据均匀的散列在不同的桶。若重写equals方法,则必须重写hashcode方法确保eqauls为true的两个对象有着相同的hash原创 2017-12-08 09:37:46 · 570 阅读 · 0 评论 -
阻塞队列
Java中的阻塞队列1.1 什么是阻塞队列(BlockingQueue)支持阻塞操作的队列。具体来讲,支持阻塞添加和阻塞移除。阻塞添加:当队列满的时候,队列会阻塞插入插入的元素的线程,直到队列不满;阻塞移除:在队列为空时,队里会阻塞插入元素的线程,直到队列不满。阻塞队列常用于生产者和消费者场景,生产者是向队列添加元素的线程;消费者是从队列取元素的线程。插入和移除原创 2017-12-08 09:42:22 · 2961 阅读 · 0 评论 -
并发库之信号量
Semaphore用来控制同时访问资源的线程数量,它通过协调各个线程,以保证合理使用公共资源。特别是公用资源有限的情况下,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发读取,但是读到内存之后,还要存储到数据库,而数据库的连接只有5个,这时候,我们必须控制线程数量为5同时获取数据库连接,否则会报无法获取数据库连接。这个时候Semaphore原创 2017-12-08 09:47:39 · 312 阅读 · 0 评论 -
并发库之同步屏障
让一组线程达到一个同步点时被阻塞,直到最后一个线程达到同步点,这时候屏障才会放行,所有被屏障拦截的线程才会继续执行。构造方法:public CyclicBarrier(intparties) {this(parties,null);}public CyclicBarrier(intparties,Runnable r) {this(parties,nul原创 2017-12-08 09:45:56 · 372 阅读 · 0 评论 -
并发库之CountDownLatch
允许一个或多个线程等待其他线程完成某一步操作。需求1:如果有三个线程,主线程,Thread1,Thread2.假设主线程必须等待线程1和线程2执行完毕,它才能继续往下执行。我们可能首先考虑到的是使用join方法。publicclass JoinClient { public static void main(String[] args) throwsI原创 2017-12-08 09:44:05 · 381 阅读 · 0 评论