JVM学习笔记

合集下载

JVM学习笔记 Java内存模型

JVM学习笔记 Java内存模型

JVM学习笔记Java内存模型一Java内存模型1、运行时数据区域1.1 程序计数器程序计数器(Program Counter Register)是一块较小的内存空间,可以看成是当前线程所执行的字节码的行号指示器。

字节码解释器工作时就是通过改变这个计数器的值来选取吓一跳需要执行的字节码指令。

线程私有,每条线程都需要有一个独立的程序计数器,各条线程之间互不影响,独立存储。

如果线程正在执行一个Java Method,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的Native Method,这个计数器的值为空(Undefined)。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError的区域。

1.2 Java虚拟机栈Java虚拟机栈(Java Virtual Machine Stacks)线程私有,生命周期与线程相同。

虚拟机栈描述的Java方法执行的内存模型: 每个方法在执行的同时,都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表存放了编译期可知的各种基本数据类型(boolean, byte, char, short, int, float, long ,double), 对象引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)其中64位长度的long,double类型的数据会占用2个局部变量空间(slot),其余的数据类型只占用1 个。

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,这个方法在运行期间不会改变局部变量表的大小。

狂神说Java--Java学习笔记(基础合集)

狂神说Java--Java学习笔记(基础合集)

狂神说Java--Java学习笔记(基础合集)笔记参考来源狂神说Java视频https:///video/BV12J41137hu 本篇笔记有点长,可以根据⽬录定位,建议配合视频学习。

预科什么是计算机1. 名称:Computer,全称电⼦计算机,俗称电脑。

2. 定义:能够按照程序运⾏,⾃动、⾼速处理海量数据的现代化智能电⼦设备。

3. 组成:由硬件和软件组成。

4. 形式:常见显⽰有台式计算机、笔记本计算机、⼤型计算机等。

5. 应⽤:科学计算、数据处理、⾃动控制、计算机辅助设计、⼈⼯智能、⽹络等领域。

硬件及冯诺依曼结构计算机硬件组成:CPU,主板,内存,电源,主机箱,硬盘,显卡,键盘、⿏标,显⽰器。

冯诺依曼结构软件及软件开发计算机软件Windows常⽤快捷键Alt+f4关闭窗⼝ Shift+Delete永久删除 ctrl+w⾃动保存死机:任务管理器结束进程基本的Dos命令打开CMD的⽅式1. 开始+系统+命令提⽰符2. win键+R+输⼊cmd (推荐使⽤)3. 在任意的⽂件夹下,按住Shift键+⿏标右击,打开命令⾏窗⼝4. 在资源管理器地址栏路径前⾯加 “cmd ”5. 管理员运⾏⽅式:命令提⽰符右键以管理员⾝份运⾏(最⾼权限运⾏)常⽤的Dos命令# 盘符切换 E:# 查看当前⽬录下所有⽂件 dir# 切换⽬录 cd /d E:\idea# 返回上⼀级⽬录 cd ..# 进⼊同级⽬录下的下⼀级⽬录 cd tmp(该⽬录下的⽂件名)# 清屏 cls (clear screen)# 退出终端 exit# 查看电脑当前IP地址 ipconfig# 打开计算器 calc# 打开画图 mspaint# 新建记事本 notepad# 在当前⽬录新建⽂件夹 md test(⽂件夹名)# 新建⽂件 cd> a.txt(⽂件名)# 删除⽂件 del a.txt(⽂件名)# 删除⽬录 rd test(⽬录名)# ping命令(复制链接进⼊Dos直接单击⿏标右键粘贴)ping 计算机语⾔发展史第⼀代语⾔:机器语⾔第⼆代语⾔:汇编语⾔第三代语⾔:⾼级语⾔⾼级语⾔C、C++、Java、C#、Python、PHP、JavaScript …⼤体上分为:⾯向过程与⾯向对象两⼤类C语⾔是典型的⾯向过程的语⾔,C++,Java是典型的⾯向对象的语⾔Java⼊门Java帝国的诞⽣Java特性与优势简单性⾯对对象可移植性⾼性能分布式多态性多线程安全性健壮性Java三⼤版本Write Once,Run AnywhereJavaSE: 标准版 (桌⾯程序,控制台开发…)JavaME: 嵌⼊式开发 (⼿机,⼩家电…),已经凉了JavaEE: E企业级开发 (Web端,服务端开发…),JavaSE为基础JDK JRE JVMJDK:Java Development Kit (Java开发者⼯具,包括 JRE,JVM)JRE:Java Runtime Environment (Java运⾏时环境)JVM:Java Virtual Machine (Java虚拟机,跨平台核⼼)安装开发环境卸载JDk1. 删除Java安装⽬录2. 删除环境变量JAVA_HOME3. 删除path下关于JAVA的⽬录4. Java -version安装JDK1. 百度搜索JDK8,找到下载地址2. 同意协议,下载电脑对应的版本,如64位操作系统下载 jdk-8u281-windows-x64.exe3. 双击安装JDK4. 记住安装路径5. 配置环境变量1. 我的电脑-》属性-》系统⾼级设置-》环境变量2. 系统变量新建–> JAVA_HOME 输⼊对应的jdk安装路径3. path变量–>% JAVA_HOME%\bin6. 测试是否成功 cmd–>Java -versionJava基础注释1. 单⾏注释 //2. 多⾏注释 /* */3. ⽂档注释 /** */标识符和关键字Java 所有的组成部分都需要名字。

[Java性能剖析]JVM内存机制-笔记

[Java性能剖析]JVM内存机制-笔记

JVM内存机制-笔记内存管理来源:在程序运行过程当中,会创建大量的对象,这些对象,大部分是短周期的对象,小部分是长周期的对象,对于短周期的对象,需要频繁地进行垃圾回收以保证无用对象尽早被释放掉,对于长周期对象,则不需要频率垃圾回收以确保无谓地垃圾扫描检测。

为解决这种矛盾,Sun JVM的内存管理采用分代的策略。

Sun JVM有4垃圾回收器:∙Serial Collector[默认]:序列垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用单线的垃圾回收方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。

基本上,在对内核的服务器上应该避免使用这种方式。

在JVM启动参数中使用-XX:+UseSerialGC启用Serial Collector。

∙Parallel Collector:并发垃圾回收器,垃圾回收器对Young Gen和Tenured Gen都是使用多线程并行垃圾回收的方式,对Young Gen,会使用拷贝策略避免内存碎片,对Old Gen,会使用压缩策略避免内存碎片。

在JVM启动参数中使用-XX:+UseParallelGC启用Parallel Collector。

∙Parallel Compacting Collector:并行压缩垃圾回收器,与Parallel Collector垃圾回收类似,但对Tenured Gen会使用一种更有效的垃圾回收策略,此垃圾回收器在暂停时间上会更短。

在JVM启动参数中使用-XX:+UseParallelOldGC启用ParallelCompacting Collector。

∙Concurrent Mark-Sweep (CMS) Collector:并发标志清除垃圾回收器,对Young Gen会使用与Parallel Collector同样的垃圾回收策略,对Tenured Gen,垃圾回收的垃圾标志线程与应用线程同时进行,而垃圾清除则需要暂停应用线程,但暂停时间会大大缩减,需要注意的是,由于垃圾回收过程更加复杂,会降低总体的吞吐量。

Jvm工作原理学习笔记

Jvm工作原理学习笔记

Jvm工作原理学习笔记一、JVM的生命周期1.JVM实例对应了一个独立运行的java程序它是进程级别a)启动。

启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static voidmain(String[] args)函数的class都可以作为JVM实例运行的起点b)运行。

main()作为该程序初始线程的起点,任何其他线程均由该线程启动。

JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程c)消亡。

当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出2.JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的二、JVM的体系结构1.类装载器(ClassLoader)(用来装载.class文件)2.执行引擎(执行字节码,或者执行本地方法)3.运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈)三、JVM类加载器JVM整个类加载过程的步骤:1.装载装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样,也采用以上三个元素来标识一个被加载了的类:类名+ 包名+ClassLoader实例ID。

2.链接链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。

完成校验后,JVM初始化类中的静态变量,并将其值赋为默认值。

最后对类中的所有属性、方法进行验证,以确保其需要调用的属性、方法存在,以及具备应的权限(例如public、private域权限等),会造成NoSuchMethodError、NoSuchFieldError 等错误信息。

3.初始化初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:调用了new;反射调用了类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类。

jvm浅解

jvm浅解

java关键字的实现原理java关键字的实现原理JVM内部的基本概念JVM的指令集本来这次应该讲讲ORM的几个框架,但是笔者还没有完全总结出来,所以这里先插入一次学习JVM的心得。

作为一个Java程序员,如果不了解JVM的工作原理,就很难从底层去把握Java语言和Java程序的运作机制。

这里先推荐一个最权威的讲解JVM的文档,大家只要查过Java API的可以在里面的一个叫“API, Language, and Virtual Machine Do cument”的标题下看到四个子标题,第一个是我们最熟悉的Java API Specification,很少会有人注意到第三和第四个子标题,分别是“The Java Language Specification”和“The Java Machine Specification”后面都带有(Download)字样,JVM的那个URL直接链接到/docs/books/vmspec/2nd-edition/这里地址。

我们可以下载到一份非常权威详细的讲解JVM原理的官方文档。

笔者业余时间花了1个星期来阅读,这里把自己的收获跟大家来分享一下,大概从这么几个方面来谈一谈:1. JVM的实现机制Java虚拟机就是一个小的计算机,有自己的指令集,有自己的文件系统,管理内部的表和数据,负责读取class文件里面字节码,然后转换成不同操作系统的CPU指令,从而使得Java程序在不同的操作系统上顺利的跑起来。

所以Window的JVM能把字节码转换成Window系统的指令集,Linux的 JVM 能把字节码转换成Linux系统的字节,同理还有Solaris,它们彼此之间是不能通用的。

最早一款的原型虽然是Sun公司开发的,但发展到现在其实任何厂商都可以自己去实现一个虚拟机,用来读取字节码转换成OS指令。

甚至我们可以认为JVM跟Java编程语言都没有关系,因为你自己哪怕用记事本写一串字节码,也可以让JVM来解析运行,只要你的字节码能通过JVM的验证。

java开发学习笔记

java开发学习笔记

java开发学习笔记GC/JVM/jiafu1115/article/details/7024323/zhguang/p/3257367.html#introductionHotSpot的GC机制。

运行时数据区包括:虚拟机栈区,堆区,方法区,本地方法栈,程序计数器虚拟机栈区:也就是我们常说的栈区,线程私有,存放基本类型,对象的引用和returnAddress ,在编译期间完成分配。

堆区,JAVA 堆,也称GC 堆,所有线程共享,存放对象的实例和数组,JAVA 堆是垃圾收集器管理的主要区域。

方法区:所有线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。

程序计数器:线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址。

JVM堆(1) 新域:存储所有新成生的对象(2) 旧域:新域中的对象,经过了一定次数的GC循环后,被移入旧域(3)永久域:存储类和方法对象,从配置的角度看,这个域是独立的,不包括在JVM堆内。

默认为4M。

Java内存分配和回收的机制概括的说,就是:分代分配,分代回收。

对象将根据存活的时间被分为:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)新域会被分为3个部分:1.第一个部分叫Eden。

(伊甸园??可能是因为亚当和夏娃是人类最早的活动对象?)2.另两个部分称为辅助生存空间(幼儿园),我这里一个称为A空间(From sqace),一个称为B空间(To Space)“停止-复制(Stop-and-copy)”清理法(将Eden区和一个Survivor中仍然存活的对象拷贝到另一个Survivor中),绝大多数刚创建的对象会被分配在Eden区,其中的大多数对象很快就会消亡。

Eden区是连续的内存空间,因此在其上分配内存极快;最初一次,当Eden区满的时候,执行Minor GC,将消亡的对象清理掉,并将剩余的对象复制到一个存活区Survivor0(此时,Survivor1是空白的,两个Survivor总有一个是空白的);下次Eden区满了,再执行一次Minor GC,将消亡的对象清理掉,将存活的对象复制到Survivor1中,然后清空Eden区;将Survivor0中消亡的对象清理掉,将其中可以晋级的对象晋级到Old区,将存活的对象也复制到Survivor1区,然后清空Survivor0区;当两个存活区切换了几次(HotSpot虚拟机默认15次,用-XX:MaxTenuringThreshold控制,大于该值进入老年代,但这只是个最大值,并不代表一定是这个值)之后,仍然存活的对象(其实只有一小部分,比如,我们自己定义的对象),将被复制到老年代把所有对象组成一个集合,或可以理解为树状结构,,基于coping算法的垃圾收集就从根集中扫描活动对象,只要可以找到的都是活动对象,如果找不到,这个对象就是凋零的昨日黄花,应该被回收总结从上面的推导可以得出很多结论,下面是前辈的经验总结与自已的认识1.JVM堆的大小决定了GC的运行时间。

第一章-Java基础笔记

第一章-Java基础笔记

第⼀章-Java基础笔记Java语⾔的概述Java是⼀门⾯向对象的语⾔,Java相对于C语⾔来说学习相对简单,它主要的三⼤特点就是:封装、继承、多态,并且只需要进⾏⼀次源码编译,在任何装有对应版本的JVM 虚拟机环境的计算机下运⾏;Java的三个版本JavaSE主要⽤于桌⾯应⽤的开发JavaME主要⽤于嵌⼊式系统的开发JavaEE主要⽤于企业级的WEB端开发和服务器开发Java环境介绍JDK - 提供了开发者的⼀些⼯具包,并包含了[JRE和JVM]JRE - Java的运⾏环境,提供了运⾏时需要的类库,并包含了[JVM]JVM - Java的虚拟⼀块内存区域,⽤于执⾏Java的代码Java跨平台交互图Java代码的运⾏机制后缀点java的⽂件会通过 javac命令进⾏⽂件的编译成⼀个能够被JVM读懂的字节码⽂件,通过加载、校验、初始化的过程都内存中,通过JVM寄存器读取⽂件中的⾏号,进⾏执⾏相关代码;注释注释是为了在编写程序时对某个类、⽅法或是⼀段代码进⾏功能作⽤的说明,它不会被编译成代码执⾏,只是起到⼀个描述作⽤,便于对代码的理解;Java中的注释分为3种:单⾏注释://多⾏注释:/* */⽂档注释:/** */对注解的内容⽣成JavaDoc⽂档DOS命令进⼊到要⽣成Doc⽂档的层级⽬录,执⾏:javadoc -encoding UTF-8 -charset UTF-8 ⽂件名称/*** @Author JavaCat7* @Description 这是⼀个⽂档注释*/public class Demo{/*** @Parameter args 对参数的描述* @Description 这是⼀个⽂档注释*/public static void main(String[] args){//这是⼀个单⾏注释System.out.println("Hello Java");/*这是多⾏注释这是多⾏注释*/}}标识符每个⼈都有名字,⽽标识符是为了给代码中的类、接⼝、⽅法、变量取⼀个名字,但它们的明⽩是有着严格规范的;规范:每个⼈都有名字,⽽标识符是为了给代码中的类、接⼝、⽅法、变量取⼀个名字,但它们的明⽩是有着严格规范的;**规范:**1.严格区分⼤⼩写;2.开头可以是$ 或 _ 或 A-Z a-z的字母组成,也可以汉字(不会这么⼲);3.可以由数字、字母或者是 $ 或 _ 组成,但数字不能⽤于开始;4.不可以包含特殊字符;5.不能以Java语⾔中的保留字作为命名;6.类名采取⼤驼峰命名法;7.⽅法和变量采取⼩驼峰命名法;8.常量采取⼤学加_进⾏命名;基本数据类型Java是强类型计算机语⾔,所有的变量必须先定义才能使⽤,对于强类型⽽⾔主要就是指的数据安全,强类型的语⾔有很多,⽐如C、C++、python...计算机存储单位换算bit(位) - 是计算内部数据存储的最⼩单元,通过8个⼆进制位进⾏表⽰;byte(字节) - 是计算机中数据处理的基本单位,通常使⽤B来表⽰;8个bit(位) = 1B(字节)1024个B(字节) = 1KB1024个KB = 1MB1024个MB = 1GB....//整数类型byte a = 1;short b = 2;int c = 3;long d = 4L;//⼩数类型float e = 5.0f;duble f = 6.0d;//字符类型char g = 'a';//布尔类型boolean h = true;boolean i = false;数据类型的转换各数值相关数据类型⽀持类型上的转换,既可以把排序级别较低的类型转换成排序级别较⼤的类型,也可以把排序级别较⾼的类型转换成级别较低的类型(但会造成数据的丢失);数据的转换强制类型转换 - 在要转换的变量前使⽤:要转换的对应数据类型如- (int)⾃动类型转换 - 在不同的数值数据类型运算中,它会以排序级别较⾼的数据类型作为基础⾃动转换int number1 = 128;//正常byte的值是 -128 - 127,强制把int类型转换成byte会造成数据的不精确byte number2 = (byte)number1;int number3 = 519;float number4 = 1.0f;//在运算过程中因为float的排序级别⽐int⾼,那么它会⾃动转换成float类型在完成运算float number5 = number3 + number4;变量,静态变量,常量及作⽤域变量是指可以变化的值,通过数据类型和变量名可以在内存中申请⼀块存储的空间,通过内存的引⽤地址可以设置改变内存中存储的值或者修改值,所有的变量必须先赋值才可以使⽤;成员变量成员变量是指在类中与⽅法同级的位置中定义的成员变量,在该位置定义的变量可以不⽤设置值就可以使⽤,因为它会对类进⾏初始化,并完成初始化赋值,就算不给他们赋值也会有默认的初始值,他们的默认初始值都是最⼩的单元;作⽤域成员位置的变量,可以在⾮静态⽅法的所有位置使⽤,如果要在静态⽅法中使⽤,需要先创建对象;public class Variable{int a; //默认为:0float b; //默认为:0.0char c; //默认为:''boolean d; //默认为:false}局部变量局部变量是指在⽅法内部定义的变量,必须要先完成初始化后,才可以被使⽤;作⽤域局部位置的变量,外部⽆法使⽤,只能在⽅法内部使⽤,可以和外部的变量名称相同;public class Variable{int number;public void method(){int number = 3;//可以和成员位置的变量名称相同}}静态变量静态变量是指被static关键字修饰的变量,被修饰的变量⼜称为类变量;作⽤域静态变量可以作⽤域与所有⽅法中,静态变量只能定义在类的成员位置;public class Variable{static int number ;public static void main(String[] arags){System.out.println(number);}public void method(){System.out.println(numbe);}}常量常量是指不能被改变的值,它在创建到成员位置必须要先完成赋值,⼀旦被创建它的值是不允许被更改的;作⽤域它的作⽤域和成员变量相同public class Variable{final int NUMBER = 3.1415926;}静态常量静态常量是指从属于类的常量,在完成初始化以后是不可以被修改的,并且被public所进⾏修饰;作⽤域它的作⽤域和静态变量相同运算符算术运算符int a = 5;int b = 2;int number = a + b; //number = 7;int number = b - a; //number = 3;int number = a * b; //number = 10;int number = a / b; //number = 2,只取整数;double number = a / (double)b; //number = 2.5int number = a % b; //number = 1;⾃增⾃减运算符int a = 1;int b;b = a++; //b = 1; 先把a的值赋值给b,后a进⾏ +1 操作;b = a--; //b = 2; a前⾯进⾏了⾃增那么就是2,先把2赋值给b,然后进⾏ -1 操作;b = ++a; //b = 2; 前⾯a进⾏了⾃减那么就是1,先对a进⾏⾃增加1,然后在赋值给b;b = --a; //b = 1; 前⾯a是2,先对a进⾏⾃减1,在赋值给b;赋值运算符int a = 5;//把 5 赋值给 a;int b = 2;//把 2 赋值给 b;a += b; // a = 7(a+b的结果在赋值给a);a -= b; // a = 3;a *= b; // a = 10;a /= b; // a = 2;a %= b; // a = 1;关系运算符int a = 5;int b = 2;a > b; //truea < b; //falsea >= b; //falsea <= b; //truea == b; //falsea != b; //true逻辑运算符boolean a = true;boolean b = false;a &&b = false;//都true则true,第⼀个条件为false就不会在看第⼆个条件,直接返回falsea ||b = true;//⼀个条件为true则true,第⼀个条件为tre就不看第⼆个条件,直接返回true! a = false;//取反a &b = false;//2个条件都要执⾏a |b = true;三元运算符int a = 5;int b = 5;a ==b ? "等于":"不等于"; //为true返回第⼀个,为false返回第⼆个流程控制语句If语句if语句就是判断条件是否成⽴,成⽴就执⾏if中的代码,不成⽴就不进⼊;boolean flag = true;if(flag){System.out.println("...");}if...else语句if...else语句就是根据判断的条件是否成⽴,成⽴⾛if语句,不成⽴⾛else语句;boolean flag = true;if(flag){System.out.println("成⽴");}else{System.out.println("不成⽴");}if...else if语句if...else if⽀持多条件的判断,只会进⼊⼀个匹配的条件;boolean flag = true;boolean fail = false;if(flag){System.out.println("条件匹配");}else if(fail){System.out.println("条件匹配");}else{System.out.println("条件都不匹配");}switch条件控制语句witch语句从JDK1.7开始可以⽀持匹配:String字符串;注意事项:每个case 后⾯必须跟⼀个数值常量或字符串常量⽤于匹配;匹配的语句后⾯需要加上break关键字,防⽌case穿透;String week = "星期⼀";switch(week){case "星期⼀":System.out.println("今天是星期⼀");break;case "星期⼆":System.out.println("今天是星期⼆");break;case "星期三":System.out.println("今天是星期⼆");break;default:System.out.println("今天星期⼏都不是");}循环控制语句for循环语句for(初始值,条件表达式,更新)for(int i = 1 ; i <= 10 ; i++){System.out.println(i);}增强for循环for(接收类型的变量,表达式)int [] arrays = {1,2,3,4,5,6,7,8,9,10};for(int i : arrays){System.out.println(arrays);}while循环语句while(条件表达式)int number = 1;while(number <= 100){System.out.println(number);number ++;}do...while循环语句do{先把语句执⾏⼀遍}while(条件表达式);boolean flag = true;do{System.out.println("先执⾏⼀遍");flag = false;}while(flag);break和continue关键字break关键字结束循环的意思;for(int i = 1; i <= 100; i++){if(i == 10){System.out.println("打印10后结束循环");break;}}continue关键字跳过当前循环,进⼊下⼀次循环;for(int i = 1 ; i <= 10; i ++){if(i % 2 == 1){continue;}System.out.println("打印:"+i);}⽅法概述:⽅法就相当于使⽤多⾏代码进⾏组合去实现的⼀个功能⽚段,对代码进⾏封装利⽤,可实现多次调⽤;⽅法的定义修饰符返回值⽅法名称(形参形参名称){⽅法体}public class Function{public static void main(String[] arags){}public void method1(){}public void method2(String name,int age){}public static void method3(){}public int method03(){int a = 3;return a;}public int method04(int a,int b){if(a == b){System.out.println(a + "和" + b + "相等");return -1;}return a > b ? a : b;}}⽅法的重载⽅法的重载是指⽅法名称相同,传递的参数类型不同,个数不同,顺序不同与返回值⽆关;这样的⽅法被称为⽅法的重载;public class Function{public int max(int a,int b) {return a > b ? a : b;}public double max(double a,double b){return a > b ? a : b;}}形参和实参形参是指在()内部的参数,实参是指被真实传递的参数;public class Function{public static vid main(String[] args){Function function = new Function();function.max(3,5);}public int max(int a,int b) {return a > b ? a : b;}}可变参数在⽅法的()中我们有时候不知道要传递多少参数,那么我们可以传递⼀个数据类型紧跟后⾯加上...来表⽰;但需要注意的是⼀个⽅法中指允许⼀个可变参,如果有其他类型的参数,那么可变参数需要写在最后⾯;可变参数本质上就是⼀个数组;public class Function{public void method(String name,int... numbers){for(int num : numbers){System.out.println(num);}}}递归递归的本质就是⾃⼰调⽤⾃⼰,它可以解决⼀些业务,但效率和开销较⼤,对⼀些⽐较⼩的运算可以使⽤;//递归求3的阶乘public class Founction{public static void main(String[] args){}public int founction(int number){int result = 1;if(number == result){return result;}return number * founction(number - 1);}}数组数组就是⼀组数据的集合,Java中的数组必须存储和数据类型相符合的值,不允许与定义的数据类型不匹配;⼀旦数组被创建出来,它的长度就不允许被改变,数组有下标(索引)的概念,都是从0开始,如果操作的数据超过数组的长度那么就会报出下标索引越界异常[ IndexOutofBoundsException ];数组的定义int[] array = new int[3];int array[] = new int[3];int array[] = {1,2,3};数组的内存模型图数组的遍历⽅式int[] arr = new int[10];//⽅式⼀for (int i = 0; i < arr.length ; i ++) {System.out.println(arr[i]);}//⽅式⼆for (int num : arr) {System.out.println(num);}⼆维数组int[][] arr = new int[3][2];String[][] strArr = {{"hello","hello"},{"hi","hi","hi",{"java","java","java","java"}}Arrays⼯具类Arrays数组的⼯具类,是jdk已经帮我们提供好的⼀套数据⼯具类,⽅便我们对数据相关进⾏⼀些操作;int[] arr = {3,51,1,33,82,22,55,53};Arrays.toString(arr);//把数组变成⼀个字符串Arrays.sort(arr);//对数组内容进⾏升序排列Arrays.fill(arr,0);//把数组的内容全部进⾏替换为0常见算法冒泡排序public static int[] arr = new int[]{5, 2, 7, 4, 6, 9, 8, 13, 19, 11, 17, 15};//冒泡排序算法public static void popArithmetic(int[] arr) {//⽐较的轮数是数组长度-1for (int i = 0; i < arr.length - 1; i++) {//每次⽐较⼀轮,需要减少1次⽐较的次数for (int j = 0; j < arr.length - i - 1; j++) {//如果前⾯的数据⽐后⾯⼤,那么就交换位置if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}System.out.println("最终结果是:" + Arrays.toString(arr));}选择排序public static int[] arr = new int[]{5, 2, 7, 4, 6, 9, 8, 13, 19, 11, 17, 15};//选择排序public static void selectOrderArithmetic(int[] arr) {//⽐较的轮数是数组长度-1for (int i = 0; i < arr.length - 1; i++) {//每⽐较⼀次,需要减少1次⽐较的次数,会把⼩的先往前排for(int j = i+1;j<arr.length;j++){if(arr[i]>arr[j]){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}System.out.println("最终结果是:" + Arrays.toString(arr));}⼆分查找public static int[] arr = new int[]{1, 2, 3 , 4, 6, 7, 8, 13, 19};//2分查找法public static void branchFind(int [] arr,int number){int startNode = 0;int endNode = arr.length-1;int middle = 0;while (startNode <= endNode){//中间的指针由开始节点和结束节点计算得来middle = (startNode+endNode)/2;if(number == arr[middle]){System.out.println("找到了");break;}else if(number < arr[middle]){endNode=middle-1;System.out.println(number+"⼩于中间值,结束节点变更为中间节点-1"); }else if(number > arr[middle]){startNode = middle+1;System.out.println(number+"⼤于中间值,开始节点变更为中间节点+1"); }else{System.out.println("没有找到该元素");break;}}}。

JVM内存机制资料笔记

JVM内存机制资料笔记

JVM内存机制资料笔记参考JDK5.0垃圾收集优化之--Don't Pause/calvinxiu/archive/2007/05/18/1614473.aspxJVM内存模型以及垃圾回收/xuwanbest/blog/item/0587d82f2c44a73d1e30892e.html对jvm内存的一些理解/midstr/archive/2008/09/21/230292.html了解JVM的内存管理与垃圾回收/jiaozhenqing/blog/item/f18b85d4c1063a07a08bb77e.htmlJava内存溢出的解决方案/yanghlcn/blog/item/029e7303917b528dd43f7cc3.htmlJava内存组成堆(Heap)运行时数据区域,所有类实例和数组的内存均从此处分配。

Java 虚拟机启动时创建。

对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

组成News Generation(Young Generation即图中的Eden + From Space + To Space)Eden 存放新生的对象Survivor Space 两个存放每次垃圾回收后存活的对象Old Generation(Tenured Generation 即图中的Old Space)主要存放应用程序中生命周期长的存活对象非堆内存JVM具有一个由所有线程共享的方法区。

方法区属于非堆内存。

它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。

它是在 Java 虚拟机启动时创建的。

除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。

例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。

组成Permanent Generation(图中的Permanent Space)存放JVM自己的反射对象,比如类对象和方法对象native heapGC策略堆JVM采用一种分代回收 (generational collection) 的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

式。

使用native函数库直接分配native内存,然后使用heap中的DirectByteBuffer 对象作为这块区域的引用,进行操作。

因为避免了heap和natived的内存复制,所以提高了性能。

判定对象存活的算法,比如引用计数法,每当被引用时,计数器加一,当引用失效时,计数器减一。

但堆对象存活判定没有使用该算法。

主流JVM实现都是使用可达性分析算法,检查对象是否与GC roots相连。

GC时,必须保证引用关系不变,因此所有线程都暂时停顿。

Hotspot在类加载完成时,把对象里每个偏移量存什么类型数据,存放在OopMap里,这样可以识别哪些位置是引用。

判定存活对象的依据:stack中引用的对象,方法区中静态属性引用的对象,方法区中常量引用的对象,本地方法引用的对象。

永久代通常不回收,回收效率也较低。

但在大量使用反射、动态代理、CGLib、等Bytecode框架、动态生成JSP以及OSGi这类频繁定义ClassLoader’的场景都需要虚拟机具备类卸载功能,以保证永久代不溢出。

GC算法:Mark-Sweep/Copying/Mark-Compact/Generational。

相关文档
最新文档