自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(46)
  • 收藏
  • 关注

原创 类加载的各个阶段

java_mirror: java的类镜像,如对应String:作用是将Klass暴露给java使用。以上都是元数据,叫instanceKlass,存在元空间(jdk8)中,但java_mirror存在堆中。准备: 为static变量分配空间,设置默认值(jdk8),和类对象一起存在堆中。静态变量分配空间和赋值是两个步骤,分配空间在准备阶段,赋值在初始化阶段。初始化: 初始化就是调用()V,虚拟机会保证这个类的构造方法的线程安全。

2023-09-11 18:44:08 43

原创 java的一些语法糖

编译时,将字符串计算hashcode,将他们的哈希码作为case,并且再用equals比较。编译时: 会写一个重写方法,其返回值一致,这个方法会调用我们写的方法。在其中,定义了一个整数数组,长度和枚举类元素个数相同,其中存case对比数字。但是在局部变量类型表中(栈帧中),其中包含了方法参数中泛型信息,这些信息没有被擦除。泛型集合取值(jdk5): 在编译泛型时会执行泛型擦除动作,即在编译为字节码时丢失了。实现了对应接口以及方法,对应代码不变,就是完整的一个内部类。

2023-09-11 18:32:01 37

原创 垃圾回收调优

新生代太大,老年代就会相应的减小,最终会导致老年代清理的FullGC变频繁,回收时间更长。先试着增大新生代空间,让minorGC那么频繁,晋升阈值同时也会上升,老年代也会好起来。重新标记的时候,不仅要扫描新生代,还有扫描老年代,如果新生代对象比较多,数据会比较长。GC频繁说明空间紧张,如果新生代内存紧张,就会导致新生代晋升阈值降低,导致情况恶化。CMS阶段: 初始标记,并发标记,重新标记,并发清理。案例: 老年代充裕情况下,发生FullGC(CMS)(jdk1.7)

2023-09-11 18:15:59 38

原创 垃圾回收器 G1

当对象引用发生改变时,就会将其加入一个写屏障,(就是将对象加入队列中,并标记为未处理)先伊甸园垃圾回收,伊甸园满了后会进行新生代垃圾回收,复制幸存对象到幸存区to。将所有新分配的字符放入一个队列,当新生代回收时,G1并发检查是否有字符串重复。新生代垃圾回收是找根对象,可达性分析,找存活对象,复制算法到幸存区。因为如果在标记的同时,用户线程将一个对象的引用取消了,该对象被标记清除,当老年代内存超过阈值时,下一次新生代垃圾回收会开启并发标记,并进行混合收集,

2023-09-11 18:14:20 33

原创 jvm垃圾回收器

开关: 自适应方式调整(堆/新生代)大小: -XX:+UseAdaptiveSizePolicy 目标: 自适应吞吐量调整目标(百分比): -XX:GCTimeRatio=ratio。开启命令:(默认开启) -XX:+UseParallelGC或-XX:+UseParallelOldGC。流程: 初步标记(stw)==>并发标记/运行==>重新标记(stw)==>并发清理/运行。且在某些情况下仍可能会发生Full GC,且Full GC的速度较慢。

2023-09-11 17:47:45 23

原创 分代垃圾回收流程机制

清除: 对没有标记的对象的起始和结束地址进行记录,放入地址列表,然后释放其中内存。整理: 将没有被标记对象释放,然后对被标记对象起始和结束地址进行整理,使更紧凑。先标记,找到被引用的对象,将这些对象从from区域复制到to区域。将内存区域划分为from和to两个部分,to是一个空区域。标记: 对GCRoot根对象所引用的对象进行标记。标记: 对GCRoot根对象所引用的对象进行标记。缺点: 没有内存碎片。优点: 不会产生碎片。缺点: 内存碎片多。

2023-09-11 14:43:17 31

原创 java中的5种引用

只被WeakReference对象引用的对象称为弱引用对象,弱引用也是用来描述非必须对象的,当强引用有引用变量指向时不会被垃圾回收,抛出OutOfMemory错误也不会回收这种对象。引用队列ReferenceQueue: 虚引用和终结器引用要配合引用队列来使用。虚引用唯一的作用就是对垃圾回收过程进行跟踪,当虚引用对象引用的对象被垃圾回收了。终结器引用和虚引用的方式很类似,它用来实现对象的finaliz()终结方法。一个对象被弱引用和这个对象没有引用的 gc垃圾回收 效果是一样的。

2023-09-11 14:41:43 33

原创 如何判断对象可以被回收

引用计数法: 定义一个计数器,记录变量当前被引用的数量,当数为0时即不被引用时,就回收。简单讲,被常量、静态变量、全局变量、运行时方法中的变量直接引用的对象,原则上不能被GC释放。可达性分析算法: 先统一扫描,确定一系列根对象,(根对象:一定不能被垃圾回收的对象):计算机底层的一些操作系统方法,可能是用c,cpp写的。如果一个对象没有被根对象 直接或者间接 的使用,就会被垃圾回收。:Object,String,HashMap等类。Thread: 正在活动的线程中使用的对象。

2023-09-11 14:24:15 27

原创 java直接内存

当ByteBuffer被垃圾回收的时候,自动会调用Cleaner类中clean方法。因为显式垃圾回收用的是FUll GC,要回收新生代和老年代,让程序暂停时间长,非常耗性能。java要想访问系统磁盘中数据,要先从系统缓冲区将数据读入到java缓冲区,clean方法中会执行Unsafe类中的freeMemory方法。但是用了ByteBuffer直接内存.会直接在系统缓冲区搞一个缓冲区,释放原理: Unsafe类,用来分配和处理直接内存的。直接内存是操作系统内存,常见于NIO操作,用于数据缓冲区。

2023-09-11 14:21:24 49

原创 jvm常量池

总结: 字符串变量只有在调用时,才会被创建,而且java底层对字符串加法做了优化,使用 StringBuilder操作,最终获取的方式是使用new的方式获取,存放在堆中。而"a","b"是常量,javac在编译期间优化,结果已经在编译期间确定为ab,无法改变。运行时常量池: 是存在.class文件中的,是每个类或接口的静态常量池在运行时的表现形式。常量池: 就是一张常量表,虚拟机指令根据常量表找到要执行的类名,方法名,参数类型,字面量等信息。

2023-09-11 14:03:10 21

原创 jvm方法区

理论上方法区应该在堆中,但不同虚拟机对此有不同实现.(jdk8后元空间,jdk1.6永久代)成员变量,方法数据,成员方法和构造器方法的代码和一些特殊方法(类构造器)//定义类 : 版本号,public,类名,包名,父类,接口。jdk1.6: MethodArea 方法区 :永久代 (堆内存)例: 创建一个类继承ClassLoader,创建1万个类,导致内存溢出。元空间是系统内存,大小方面更充裕,并且其垃圾回收机制由元空间自行管理,效率更好。//二进制字节码文件。

2023-09-11 12:41:38 20

原创 jvm本地方法栈

本地方法栈与虚拟机栈的功能和结构非常相似,都由多个栈帧组成,每个栈帧对应一个方法的调用和执行。本地方法栈可通过本地方法接口(JNI)访问虚拟机内部的运行时数据区,也可直接操作本地内存和寄存器。方法被调用时,会创建新的栈帧并压入栈顶,方法执行结束时,会弹出栈顶的栈帧并返回结果。native修饰的方法,一般是用c或者cpp写的,这些方法是本地方法,可以被java调用。jvm中方法调用一定要用到方法栈,所以就有了本地方法栈。本地方法栈执行一些本地方法,其他与方法栈相同。本地方法栈的大小可以是固定的或动态扩展的,

2023-09-11 12:18:05 66

原创 jvm虚拟机栈

每个线程在创建时都会创建一个虚拟机栈,它由多个栈帧组成,每个栈帧对应一个方法的调用和执行。虚拟机栈遵循先进后出的原则,当一个方法被调用时,就会创建一个新的栈帧并压入栈顶,当一个方法执行结束时,就会弹出栈顶的栈帧并返回结果。虚拟机栈的大小可以是固定的或者动态扩展的,如果栈的深度超过了虚拟机允许的最大深度,就会抛出StackOverflowError异常;线程运行时需要的内存空间,不同的线程不同,用于存储每个线程执行的方法的信息。栈内存是方法调用留下的栈帧内存,每次方法调用结束后,会被弹出栈,自动被回收。

2023-09-11 12:09:14 32

原创 程序计数器(寄存器)

然后执行线程2的代码,如果也在时间片内没有执行完,会暂存线程2,继续执行线程1..其中暂存的是存储下一个jvm指令执行的地址,存在对应线程计数器中,不同线程单独存放。不会内存溢出: 因为程序计算器所维护的只是下一条待执行的命令的地址,内容很少就一条。如果没有时间片,CPU就会一直等待一个进程或线程完成它的所有任务,其他进程或线程。操作系统分配给正在运行的进程/线程的一段CPU时间,用来实现多任务的并发执行。作用: 在jvm指令的执行过程中,记录下一个指令的执行地址,一条一条执行。

2023-09-11 12:00:11 54

原创 JVM是什么?

一次编译,到处运行: 屏蔽了字节码文件和底层操作系统差异,对外提供一致的运行环境。JVM 虚拟机: 屏蔽java文件和底层的操作系统的差异。当JVM要调用某个对象的某个方法时,会先从对象头中获取该对象所属类的类型信息。再根据常量池中的符号引用找到该类的方法表,再据方法表中的索引找到具体代码。路线: 内存结构 方法区,Heap堆,JVM虚拟机栈,程序计数器,本地方法栈。3. Java 程序从编译为字节码到加载到运行的全流程,各个阶段的优化处理;

2023-09-11 11:58:23 38

原创 java中不可变集合

static Map of (E...Elements) 创建一个具有指定元素的Map集合对象。static list of (E...elements) 创建一个具有指定元素的List集合对象。static Set of (E...elements) 创建一个具有指定元素的Set集合对象。注意: Map集合的of方法是有限的,最多只能存20个参数,10个键值对。这个集合不能添加,不能删除,不能修改.

2023-07-21 15:44:18 47

原创 集合工具类Collections

void fill(List<T> list,T obj) 使用指定的元素填充元素。void copy(List<T> dest,List<T> src) 拷贝集合中的元素。void sort(List<T> list,Compartor<T> c) 指定规则排序。

2023-07-21 15:43:44 24

原创 java中可变参数

例: public static int getSum(int...args){}如果方法除了可变参数外,还有其他参数.在定义方法的时候要将其他参数放可变参数之前。调用: getSum(1,2,3,4);底层: 可变参数底层就是java创建的一个数组。细节: 在方法的形参中最多只有一个可变参数。可变参数: 方法的参数个数可以发生变化。格式: 属性类型...名字。

2023-07-21 15:42:04 27

原创 Java双列集合Map详

多态创建 Map map=new HashMap();Set entrySet() 获取map的键值对集合。如果不是null,就调用equals方法比较,相同就覆盖原来的元素,键和值这个整体,我们称之为键值对或者键值对对象,在java中叫做Entry对象。在添加数据时,如果键不存在,就将键值对添加到map集合中。put方法底层创建一个Entry对象,记录键和值。如果键存在,那么会将原有的键值对覆盖,并返回被覆盖的值。

2023-07-21 15:41:23 77

原创 java中Lambda表达式

如果Lambda表达式的方法体只有一行,大括号,分号,return可以省略,要同时省略。函数式编程: 一种思想特点,忽略面向对象的复杂语法,强调做什么,而不是谁去做。使用前提: Lambda表达式只能简化函数式接口的匿名内部类的写法。函数式接口: 有且只有一个抽象方法的接口叫函数式接口,如果参数只有一个, () 参数括号可以省略。省略的核心思想: 可推导,可省略.Lambda格式: ()->{}好处: 匿名函数,简洁灵活。-> :固定格式。

2023-07-21 15:39:54 23

原创 java中Set集合详

去重且保证存储顺序 用LinkedHashSet,基于哈希表,双链表,效率低于HashSet。对象类型比较,实现Comparable接口,重写方法,指定比较规则,存红黑树。哈希值: 对象的整数表现形式,方法定义在object类,所有对象都可以调用,在小概率情况下,不同属性的对象或地址值计算的hash值一样(哈希碰撞)保证储存和取出的顺序一致,每一个元素额外的多了一个双链表的机制记录储蓄的顺序。去重 用HashSet,基于哈希表,双链表,红黑树。

2023-07-21 15:33:57 24

原创 java中List集合详

/获取列表迭代器对象。E set(int index,E e) 修改指定索引处元素(返回被修改的元素)List特有方法: void add(int index,E e) 在指定索引添加元素。boolean remove(E e) 把给定对象在当前集合中删除。E get(int index) 获取指定索引处元素。常用方法: boolean add(E e) 添加元素。添加第一个元素的时候,底层会创建一个新的长度为10的数组。

2023-07-21 15:33:24 29

原创 java中泛型

例 public static void method(ArrayList

2023-07-21 15:32:45 22

原创 java数据结构基本

每一个节点有储存节点的颜色,可以是红或者黑,不是高度平衡的,按照红黑规则实现。如果一个节点没有子节点或父节点,那就设子节点为Nil,叫叶节点,黑色。每一个节点,从该节点到其后代节点的简单路径上,都包含相同数目黑色节点。单向链表: 节点: 数据,下一个节点地址值,(元素在内存中是不连续的)红黑树: 节点: 父节点地址,值,左子节点,右子节点,颜色。双向链表: 节点: 前一个节点的地址值,数据,后一个节点的地址值。节点: 父节点地址,左子节点地址,右子节点地址,值。

2023-07-21 15:31:32 31

原创 java中Collection单列集合

boolean remove(E e) 把给定对象在当前集合中删除。List的实现类: ArrayList,LinkedList,Vector(过时)while (it.hasNext()){//判断下一个存不存在。boolean hasNext() 判断当前指向的位置是否有元素。int size() 返回当前集合中元素的个数。常用方法: boolean add(E e) 添加元素。不重复: 集合中不同元素,值不能相同。

2023-07-21 15:30:35 26

原创 Java中包装类

static int parseXxx(String s) 将字符串转换为int类型。包装类 基本数据类型对应的引用类型 万物皆对象思想的应用。jdk5之前要独立获取,用构造方法或者静态方法,如果要操作,就要先转换为int再操作,再转换回去。在开发中,-128~127用的比较多,如果用到了,就不会创建对象,而是直接使用这个对象。所以,valueOf方法在创建两次-128~127之间的数字的时候,其实是同一个对象。这两种构造方法的区别,

2023-07-20 13:29:36 19

原创 java中爬虫

正则外部使用: $组号 如: replaceAll("(.)\\1+","$1")正则) 获取不是指定内容的前面部分 java(?:正则) 获取所有 java(?判断一个字符串开始部分和结束部分是否一致,开始部分内部每一个字符也要一致。=正则) 获取前面部分 java(?捕获分组 正则表达式是按照()来分组的。// (.):把首字母看做一组。

2023-07-20 13:28:40 591

原创 java中正则表达式

\ 表示单独\ 第一个\是转义,改变了后面的\的含义。[a-z&&[^m-p]]: 除了m到p外的小写字母。[a-z&&[^bc]]: 除了bc外的小写字母。字符类: [abc] : 只能是a或b或c。[a-d[m-p]]: a到d,或 m到p。X{n,m} 至少n但不超过m次。X{n} X,正好n次。X* X,0次或多次。X+ X,一次或多次。X{n,} 至少n次。

2023-07-20 13:27:21 24

原创 Java中的克隆方法

创建Gson对象 Gson gson=new Gson();浅克隆: 就是直接拷贝,并没有创建新对象,地址值不变,克隆对象一旦被修改,原对象也修改了。cloneable接口表示,一旦实现,当前类对象就可以被克隆,不然不能被克隆。如果是引用数据类型,就会再new一个新对象,将原来对象的数据拷贝来。如果一个接口没有抽象方法,那么说明,当前接口是一个标记型接口。方法在底层会创建一个对象, 并将原对象数据拷贝。深克隆: 就是创建新对象,地址值不同。下面是数组要重写的深克隆。

2023-07-20 13:26:19 106

原创 Java中 内部类

2直接创建:外部类名.内部类名 对象名=外部类对象.内部类对象;外部类名.内部类名 对象名 = new 外部类名.内部类名()应用: 当方法的参数是接口或类时,可以传递这个接口的实现类对象或子类对象。还可以用new 父类名或接口名(){重写方法}.equal方法等,直接调用。创建对象 父类名或接口名 对象名=new 父类名或接口名 ();父类名或接口名 对象名=new 父类名或接口名(){重写方法};将内部类定义在方法中,就是局部内部类,类似方法中的局部变量。

2023-07-20 13:22:22 29

原创 java中 接口interface

接口的设计理念是将不可变的东西封装到一起,将可变的东西放到实现中。jdk8之后,可定义有方法体的方法(默认,静态)(default,static)类与接口 实现关系,可以单实现,也可以多实现,还能继承一个类同时实现多个接口。原因: jdk8: 只要接口的内容变化,那么所有的实现类都要修改,接口的设计理念是将不可变的东西封装到一起,将可变的东西放到实现中。即接口升级的时候,避免所有现有实现类代码报错。当一个方法的参数是接口时,可以传递接口所有实现类的对象,这个方式叫接口多态。

2023-07-20 13:19:51 30

原创 java中抽象类

抽象方法: 将共性的行为(方法)抽取到父类后,由于每一个子类的执行的内容是不一样的。当又有一个具有相似的组件产生时,只需要实现该抽象类就可以获得该抽象类的那些属性和方法。所以,在父类中不能确定具体的方法体的时候,就可以定义为抽象方法。抽象类: 如果一个类中存在抽象方法,那么该类就必须声明为抽象类。把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护。抽象类的子类: 要么重写抽象类中的所有抽象方法。有抽象方法的类一定是抽象类。抽象类中不一定有抽象方法。

2023-07-20 13:13:12 30

原创 Java中代码块 {}

已经淘汰了,因为不够灵活,一旦写了,会让所有构造方法都执行代码块。在创建本类对象的时候,会先执行构造代码块,再执行构造方法。应用: 在需要一些数据初始化的时候就需要静态代码块。写在方法中的代码块,一般用来限制局部变量的生命周期。但是现在已经不怎么用了,因为内存容量已经足够大了。特点: 通过static关键字修饰,可以将多个构造方法中重复的代码抽取出来。一般可以之间写一个方法,直接调用就行。并且自动触发,只执行一次。随着类的加载而加载,写在成员位置的代码块。

2023-07-20 13:11:11 36

原创 Java中权限修饰符

public 可 可 可 可。protected 可 可 可。特例 如果方法中代码时抽取其他方法中的共性代码,那这个方法一般也私有。

2023-07-20 13:10:24 20

原创 Java中final关键字

private保证地址不能被获取,并且没有get和set方法。字符串的底层时用数组储存的,用private和final修饰。变量储存的地址值不能发生改变,对象内部可以改变。多个单词:全部大写,每个单词之间用下划线隔开。常量,只能被赋值一次,一旦赋值,不能改变。当前方法时最终方法,不能被重写。final修饰的变量时基本数据类型时。final修饰的变量时引用数据类型时。当前类时最终类,不能有子类。变量储存的数据值不能被改变。final保证地址值不变。所以字符串不能被改变。

2023-07-20 13:08:15 23

原创 java包与导包

公司域名反写+包的作用,全部英文小写,见名知意 例:com.alibaba.com.service。如果使用两个包中的同名类,需要用全类名。使用java.lang包中的类时,不需要导包。包的文件夹,用来管理各种不同功能的java类。导包 就是使用其他包下的其他类的方法。在使用同一个包的情况下不用导包。

2023-07-19 20:12:40 32

原创 java多态

好处: 使用父类类型作为参数,可以接受所有子类对象,体现多态的扩展性和便利。定义方法时使用父类作为参数,那么就可以接受所有的子类对象,体现多态的扩展性和便利。因为编译的时候,会加载测试类,父类,和子类的class文件,就是编译的时候会看左边的父类中有没有这个变量,如果没有,就编译失败。编译的时候还是看左边的父类中有没有这个方法,如果没有就编译失败。表现形式 Fu f=new zi();运行的时候,实际获取的时左边的父类的变量。运行的时候,实际获取的是右边子类的方法。

2023-07-19 20:12:00 25

原创 java继承相关

当类与类之间,有相同的内容,并满足子类是父类的一种,就可以考虑继承优化。格式: 子类和父类中一模一样的方法声明,就称这个方法是重写的方法。原因: 子类再初始化的时候,会使用父类中的数据,父类没有初始化,子类初始化之前,一定要调用父类构造方法先完成父类数据的初始化。子类中所有的构造方法默认先访问父类中的无参构造,再执行自己。就近原则,先局部,后成员,再就是父类的成员变量...子类可以在父类的基础上,增加其他功能,让子类更强大。当父类方法不能满足子类现在的需求时,要进行方法重写。

2023-07-19 20:11:03 18

原创 java 继承的底层

在内存中,一个子类对象在堆中的空间是分割开的,分两部分,一部分存子类成员变量,一部分存父类的。创建对象的时候,会从最顶级的父类开始,设置虚方法表,如果要调用父类的成员方法,如果虚方法表中没有,就会采用就近原则,向父类中一级一级往上查找。虽然无法调用父类中的私有变量,但是子类可以继承父类所有的成员变量。虚方法表中查找,虚方法表中记录了经常可能被使用的方法。所以,只有父类中的虚方法才能被子类继承。误区2 父类中非私有的成员变量,被子类继承。只有父类中的虚方法才能被子类继承。加载object虚方法表,

2023-07-19 20:10:02 31

原创 java中static关键字

应用: 工具类的创建,私有化构造方法,方法都是用static定义,方便调用。静态方法如果调用了非静态方法,可能会出现被调用方法的类对象未加载的问题。因为main静态的,所有调用的方法也要是静态的。静态变量是优先于对象而出现的,随着类的加载而加载。如果实在要调用非静态的方法也可以,创建类对象,可以用.方法名的方式调用。调用方式: 类名调用 对象名调用。原因: 静态是随着类的加载而加载的,和非静态的创建的时机不同。静态方法的调用是用类名调用。

2023-07-19 20:06:49 17

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除