Java
文章平均质量分 76
Dream_Ryoma
这个作者很懒,什么都没留下…
展开
-
虚拟机类加载机制(七)——类加载的过程(初始化)
类初始化时类加载过程的最后一步,前面的类加载过程中,除了在加载阶段(类加载过程的一个阶段)应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的java程序代码。在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者可以从另外一个角度来表达:初始化阶段是执行类构造器...原创 2018-10-21 14:42:11 · 219 阅读 · 0 评论 -
虚拟机类加载机制(八)——类加载器
虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到java虚拟机外部去实现,以便让应用程序自己决定如何取获取所需要的类。实现这个动作的代码模块称为“类加载器”。类加载器可以说是java语言的一项创新,也是java语言流行的重要原因之一。1.类与类加载器:类加载器虽然只用于实现类的加载动作,但它在java程序中起到的作用却远远不限于类加载阶段。...原创 2018-10-21 14:42:41 · 182 阅读 · 0 评论 -
java克隆注意事项
对象拷贝时,类的构造函数不会被执行package PrototypePattern.cloneTest;public class TestObject implements Cloneable{ public TestObject() { System.out.println("构造函数执行"); } @Override prot...原创 2018-10-09 18:07:02 · 266 阅读 · 0 评论 -
垃圾收集器与内存分配策略(五)——垃圾收集器
(1)Serial收集器Serial收集器是JDK1.3之前虚拟机新生代收集的唯一选择。这个收集器是一个单线程的收集器,单线程的意义是指在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。它的优势在于对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,可以获得最高的单线程收集效率。(2)ParNew收集器ParNew收集器是Serial收集器的多线程...原创 2018-10-25 14:50:16 · 181 阅读 · 1 评论 -
垃圾收集器与内存分配策略(六)——内存分配与回收策略
对象的内存分配,往大方向上讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地栈上分配),对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。(1)对象优先在Eden分配大多数情况下...原创 2018-10-25 14:57:35 · 196 阅读 · 0 评论 -
JVM运行期优化
介绍四种最具有代表性的优化技术:(1)语言无关的经典优化技术之一:公共子表达式消除如果一个表达式E已经计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E的这次出现就成为了公共子表达式。对于这种表达式,没有必要花时间再对它进行计算,只需要直接用前面计算过的表达式结果代替E就可以了。如果这种优化仅限于程序的基本块内,便称为局部公共子表达式消除,如果这种优化的范围涵盖了多个基...原创 2018-10-26 09:35:59 · 211 阅读 · 0 评论 -
JVM运行时数据区
JVM在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着JVM进程的启动而存在,有的区域则依赖用户线程的启动和结束而建立和销毁。JVM锁管理的内存将会包括以下几个运行时数据区域:(1)程序计数器:程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念里,字节码解释器工...原创 2018-10-23 21:11:39 · 157 阅读 · 0 评论 -
虚拟机对象的创建、布局、访问
知道了虚拟机内存的概况,了解了内存中放了些什么后,那虚拟机中对象是如何创建、如何布局以及如何访问的呢?对于这种涉及细节的问题,必须把讨论范围限定在具体的虚拟机和集中在某一个内存区域上才有意义。本篇基于HotSpot虚拟机以及堆为例,探究虚拟机中对象的创建、布局以及访问。(1)对象的创建:java是一门面向对象的语言,在java程序中无时无刻都有对象被创建出来。在语言层面上,创建对象通常仅仅...原创 2018-10-23 21:12:03 · 178 阅读 · 0 评论 -
垃圾收集器与内存分配策略(一)—— 概述
java运行时数据区域有很多个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。而java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间才能知道会创建...原创 2018-10-25 14:03:49 · 135 阅读 · 0 评论 -
垃圾收集器与内存分配策略(二)——对象已死吗
在堆里面存放着java中几乎所有对象的实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还存活着,哪些已经死去。(1)引用计数算法:引用计数算法是给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。客观地说,引用计数法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的...原创 2018-10-25 14:26:05 · 141 阅读 · 0 评论 -
垃圾收集器与内存分配策略(三)——垃圾收集算法
(1)标记-清除算法算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,它的标记过程发生在对象标记判定时。它的主要不足有两个:一是效率问题,标记和清除两个过程的效率都不太高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃...原创 2018-10-25 14:29:12 · 140 阅读 · 0 评论 -
垃圾收集器与内存分配策略(四)——HotSpot的算法实现
(1)枚举根节点从可达性分析中从GC Roots节点找引用链这个操作为例,可作为GC Roots的节点主要在全局性的引用(例如常量或类静态属性)与执行上下文(例如栈帧中的本地变量表)中,现在很多应用仅仅方法区就有数百兆,如果要逐个检查这里面的引用,那么必然会消耗很多时间。另外,可达性分析对执行时间的敏感还体现在GC停顿上,因为这项分析工作必须在一个能确保一致性的快照中进行——这里“一致性”...原创 2018-10-25 14:45:37 · 148 阅读 · 0 评论 -
OutOfMemoryError异常
(1)堆溢出java堆用于存储对象实例,只要不断创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。如果发生异常,可以在程序运行时搭配-XX:+HeapDumpOnOutOfMemoryError参数让虚拟机在出现内存溢出异常时Dump出当前的内存堆快照以便事后进行分析。解决这个区域的异常,一般...原创 2018-10-24 23:13:31 · 226 阅读 · 0 评论 -
队列实现栈(java)
栈的特性是后进先出。栈的两个主要操作,一个是出栈,一个是入栈。队列的特性是先进先出。队列的两个主要操作,一个是队尾追加元素,一个是队首取出元素。要用队列实现栈,那么需要两个队列,一个正式队列,一个预备队列。正式队列相当于栈,用来存储入栈的元素;预备队列用来在出栈的时候,将队首到队尾前一个元素进行临时存储,待出栈操作完成后,再将预备队列中的元素取出放到正式队列中。代码实现如下:pa...原创 2019-03-13 16:20:23 · 452 阅读 · 0 评论 -
用栈实现队列(java)
栈的特性是后进先出。栈的两个主要操作,一个是出栈,一个是入栈。队列的特性是先进先出。队列的两个主要操作,一个是队尾追加元素,一个是队首取出元素。要用栈实现队列,那么需要两个栈,一个正式栈,一个预备栈。正式栈相当于队列,用来存储进入队列的元素;预备栈用来在取出队首元素的时候,将栈顶到栈底上一个元素进行临时存储,待取出队首元素操作完成后,再将预备栈中的元素取出放到正式栈中。代码实现如下:...原创 2019-03-13 16:48:44 · 477 阅读 · 0 评论 -
虚拟机类加载机制(六)——类加载的过程(解析)
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用在class文件中是以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等类型的常量出现,那解析阶段中所说的直接引用与符号引用又有什么关系呢?符号引用:以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符...原创 2018-10-18 09:19:49 · 239 阅读 · 0 评论 -
面向对象四大特性
抽象:把现实生活中的某一类东西提取出来,用程序代码来表示,抽象出来的程序代码叫做类或接口。抽象分为两个部分:数据(可以理解为现实事务的特征)抽象和行为抽象。数据抽象:现实生活中事务的特征,对应类中的属性(比如现实生活中人有眼睛、鼻子等,抽象到类中就是眼睛属性、鼻子属性)。 行为抽象:现实生活中事务的行为,对应类中的方法(比如现实生活中人会吃饭、睡觉等,抽象到类中就是吃饭方法、睡觉方法)。...原创 2018-09-28 14:49:53 · 286 阅读 · 0 评论 -
File类详解
1.java.io.File类是java中很常见的一个类。该类有一下特性: (1)封装了文件或路径。 (2)不能用来创建文件,即在程序中创建一个File对象,并不会在机器上创建一个文件(感兴趣的同学可以去实践一下)。那创建的一个File对象不会创建一个文件,那这个File对象到底是什么呢?我个人理解这个File对象其实就是机器上某个文件的对象的引用。 (3)不能用来向文件中写内容...原创 2018-06-29 18:32:33 · 5509 阅读 · 1 评论 -
PrintWriter类详解
1.java.io.PrintWriter是java中很常见的一个类,该类可用来创建一个文件并向文本文件写入数据。可以理解为java中的文件输出,java中的文件输入则是java.io.File。2.常用的构造方法:注:java.io.PrintWriter的构造方法并不局限于一下范例,java.io.PrintWriter构造方法的参数也可以是字节流。因为本篇文章主要讲关于文件的操作,所以参数是...原创 2018-07-01 13:57:08 · 91913 阅读 · 3 评论 -
多线程一(线程的概念、状态)
java的重要功能之一就是内部支持多线程,即在一个程序中允许同时运行多个任务。在许多程序设计语言中,多线程都是通过调用依赖于系统的过程或函数来实现的。 线程的概念 一个程序可能包含多个并发运行的任务。线程是指一个任务从头至尾的执行流。线程提供了运行一个任务的机制。对于java而言,可以在一个程序中并发地启动多个线程。这些线程可以在多处理器系统上同时运行,也可以在单处理器系统上同时运行(可...原创 2018-08-15 10:47:59 · 176 阅读 · 0 评论 -
多线程二(线程池)
线程池的引入在执行单一任务的时候,我们通常都是先定义一个任务,然后创建一个线程,去执行这个任务。这是没问题的,但是这种方式对与大量的任务而言是不够高效的。为每个任务开始一个新线程可能会限制流量并且造成性能降低。而线程池是管理并发执行任务个数的理想方法。线程池技术在实际开发中的应用在实际开发中,服务器完成一个任务的时间由三部分组成:创建线程的时间(T1),线程执行任务的时间(T2)以及销毁线...原创 2018-08-15 14:56:38 · 126 阅读 · 0 评论 -
多线程三(线程同步)
前面已经介绍过,在操作系统中,进程是资源分配的单位,线程是调度运行的单位。一个进程中可以存在多个线程,这多个线程共享进程的资源。线程具有并发性,也就是说,一个进程内的多个线程在完成任务的时候,是有可能同时使用到进程内的同一个资源,这个时候就会产生竞争,这也是多线程程序中的一个普遍问题,在java中,这种现象叫做竞争状态。synchronized关键字为避免竞争状态,应该防止多个线程同时进入程...原创 2018-08-15 17:19:15 · 566 阅读 · 0 评论 -
多线程四(阻塞队列、信号量、同步集合)
阻塞队列队列是一种先进先出的数据结构。元素被追加到队列末尾,然后从队列头删除。在优先队列中,元素被赋予优先级,当访问元素的时候,拥有最高优先级的元素首先被删除。阻塞队列在试图向一个满队列添加元素或者从空队列中删除元素时会导致线程阻塞。java中阻塞队列的实现由java.util.concurrent.BlockingQueue接口提供,该接口扩展了java.util.Queue,并且...原创 2018-08-16 10:29:20 · 657 阅读 · 0 评论 -
多线程七(锁优化)
高效并发是从JDK1.5到JDK1.6的一个重要改进,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁等,这些技术都是为了在线程之间更高效地共享数据,以及解决竞争问题,从而提高程序的执行效率。 自旋锁与自适应自旋 互斥同步对性能最大的影响是阻塞的实现,挂起线程和回复线程的操作都需要转入内核态执行,这些操作给系统的...原创 2018-08-22 15:08:21 · 176 阅读 · 0 评论 -
内存模型(一)
多任务处理在现代计算机操作系统中几乎已经是一项必备的功能了。在许多情况下,让计算机同时去做几件事情,不仅是因为计算机的运算能力台强大,还有一个很重要的原因是计算机的运算速度与它的存储和通信子系统速度的差距太大,大量的时间多花在磁盘I/O、网络通信或者数据库访问上。于是,让计算机处理多项任务则是最容易也是最有效利用计算机运算速度的方式。除了充分能利用计算机处理器的能力外,一个服务端同时对多个客户...原创 2018-08-17 18:26:30 · 707 阅读 · 0 评论 -
内存模型(二)
原子性、可见性、有序性 java内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性这3个特征来建立的。(1)原子性由java内存模型来直接保证的原子性操作包括read、load、use、assign、store和write,我们大致可以认为基本数据类型的访问读写是具备原子性的(long和double的非原子性协定)。如果应用场景需要一个更大范围的原子性保证,java内存...原创 2018-08-20 18:15:47 · 129 阅读 · 0 评论 -
多线程五(java线程补充知识)
并发不一定要依赖多线程,但是在java里的并发大多与多线程脱不开关系。线程的实现线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和调度执行分开,各个线程既可以共享进程资源,如内存地址、文件I/O等,又可以独立调度。主流的操作系统都提供了线程实现,java语言则提供了在不同硬件和操作系统平台下对线程操作的统一处理,每个已经执行start方法且还未结束的java.la...原创 2018-08-20 16:58:43 · 158 阅读 · 0 评论 -
虚拟机类加载机制(一)——概述
代码编译的结果是从本地机器码变成字节码,即java文件变成class文件。class文件中有很多信息,这些信息最终都要加载到虚拟机中才能运行和使用。而虚拟机如何加载这些class文件呢?class文件中的信息加载到虚拟机后会发生什么变化呢?虚拟机类加载机制系列文章中的class文件不是特指存在于具体磁盘中的文件,而是一串二进制的字节流,无论以何种形式存在的都可以。虚拟机把描述类的数据从cl...原创 2018-10-11 10:43:22 · 157 阅读 · 0 评论 -
虚拟机类加载机制(二)——类加载的时机
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段。其中验证、准备、解析这三个阶段统称为连接(Linking)。七个阶段的发生顺序如下图: 七个阶段中,加...原创 2018-10-11 14:06:30 · 158 阅读 · 0 评论 -
虚拟机类加载机制(三)——类加载的过程(加载)
加载是类加载过程的一个阶段。在加载阶段,虚拟机需要完成以下3件事情:(1)通过一个类的全限定名来获取定义此类的二进制字节流。(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。(3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。虚拟机规范的这3点要求其实并不算具体,因此虚拟机实现与具体应用的灵活度都是相当大的。...原创 2018-10-11 15:08:44 · 166 阅读 · 0 评论 -
虚拟机类加载机制(四)——类加载的过程(验证)
验证是连接阶段的第一步,这一阶段的目的是为了确保class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。java语言本身是相对安全的语言,使用纯粹的java代码无法做到诸如访问数组边界以外的数据、将一个对象转型为它并未实现的类型、跳转到不存在的代码行之类的事情,如果这样做了,编译器将拒绝编译。但是class文件不一定要求用java源码编译出来,可以使用任何途径产生...原创 2018-10-11 17:12:26 · 277 阅读 · 0 评论 -
虚拟机类加载机制(五)——类加载的过程(准备)
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。需要强调的是,这个时候进行内存分配的仅包括类变量,即被static修饰的变量,不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在java堆中。其次,这里所说的初始值通常情况下是数据类型的零值,假设一个类变量的定义为: public static int value = 123;...原创 2018-10-17 19:29:46 · 188 阅读 · 0 评论 -
RMI执行rmic生成stub类报错找不到文件
1.配置环境变量: key:jdk,value:jdk安装目录jdk的bin目录下。 key:jre,value:jdk安装目录jre的bin目录下。 比如:我的jdk安装在E盘java文件夹中,那么新增环境变量值为:jdk---E:\Java\jdk\bin,jre---E:\Java\jre\bin。 在path变量中添加%jdk%;%jre%。2.在classpath...原创 2018-05-15 14:39:46 · 1557 阅读 · 0 评论