字节码

带着新人看java虚拟机01

淺唱寂寞╮ 提交于 2020-02-16 04:06:03
1.前言(基于JDK1.7)      最近想把一些java基础的东西整理一下,但是又不知道从哪里开始!想了好久,还是从最基本的jvm开始吧!这一节就简单过一遍基础知识,后面慢慢深入。。。   水平有限,我自己也是很难把jvm将清楚的,我参考一本书《深入java虚拟机第二版》(版本比较老,其实很多大佬的博客都是参考的这本书的内容。。。),电子档pdf文件链接:https://pan.baidu.com/s/1bxs4i0gnVpz7Lkjl2fxS9g 提取码:n5ou ,有兴趣的小伙伴可以自己下载自己好好看看;   所谓jvm,又名java虚拟机。我们平常写java程序的时候几乎是感觉不到jvm的存在的,我们只需要根据java规范去编写类,然后就可以运行程序了,当然只有我们程序出现bug了,我们才有可能在控制台上看到一些jvm报错的信息,比如内存溢出异常等。   java之所以能够跨平台,就是因为jvm屏蔽了各个操作系统之间的差异,举个形象的例子,我们手机要充电吧,但是充电的方式有很多种,你可以直接数据线插到插座充电,也可以用数据线插到电脑USB口充电,一个是电脑一个是插座,为什么都能给手机充电呢?原因就是有数据线屏蔽了插座和电脑的差异,对于手机来说,它是看不到数据线另外一头连接的是什么设备,只知道有电通过数据线向自己传过来就ok了,顺便一提,这也是所谓的适配器的原理!  

JVM 内存分析

故事扮演 提交于 2020-02-15 20:24:16
简述JVM垃圾回收机制 垃圾回收机制时Java提供的自动释放内存空间的机制. 垃圾回收机制时JVM自导的一个线程,用于回收没有被引用的对象. JVM有一个运行时的数据区来管理内存.其主要包括五大部分:程序计数器,虚拟机栈,本地方法栈,方法区,堆. 其中程序计数器,虚拟机栈,本地方法栈 每个线程私有的内存空间,和线程的生命周期相同.如栈中每个栈帧分配多少的内存基本上在类结构确定时就以几个确定了.无需考虑内存回收的问题. 方法区和堆就和上面不一样了,一个接口的多个类实现需要的内存可能不一样,只有在程序运行期才指导会创建哪些对象,这部分内存的分配和回收都是动态的, GC主要关注的就是该部分内存. Java虚拟机数据区域 黄色: 由所有线程共享的数据区. 绿色: 线程隔离的数据区. 程序计数器:当前线程所执行的字节码的行号指示器,在虚拟机的概念模式里,字节码解释器工作就是通过改变程序计数器的值来选择下一跳需要执行的字节码指令,分支,循环,跳转,异常处理,线程回复等基础功能都要依赖这个基础器来完成. Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,指挥执行一条线程中的指令.因此,为了线程切换之后能够恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线成之间的计数器互不影响,独立存储. 如果线程正在执行一个Java方法

Java 之 类加载器

百般思念 提交于 2020-02-15 13:17:02
一、类加载器概述   在开发中会遇到 java.lang.ClassNotFoundException 和 java.lang.NoClassDefError,想要更好解决这类问题,或者在一些特殊的应用场景,比如需要支持类的动态加载或需要对编译后的字节码文件进行加密解密操作,那么需要你自定义类加载器,因此了解类加载器及其加载机制成为了Java开发必备技能之一。 二、四种类加载器   1、引导类加载器(Bootstrap Classloader),又称为根类加载器      它负责加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar 等或 sun.boot.class.path 路径下的内容),是用原生代码(C/C++)来实现的,并不继承自 java.lang.ClassLoader,所以通过 Java 代码获取引导类加载器对象将会得到 null。(只有核心类库如 String 才使用 引导类加载器)   2、扩展类加载器(Extension Classloader)      它由 sun.misc.Launcher$ExtClassLoader 实现,是 java.lang.ClassLoader 的子类,负责加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar或java.ext.dirs路径下的内容)   3、应用程序类加载器

深入分析synchronized的实现原理

烈酒焚心 提交于 2020-02-15 00:38:06
基础概念   synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时可以保证共享变量对内存可见性。   Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是当前实例对象 静态同步方法,锁是当前类的class对象 同步方法块,锁是括号里面的对象   当一个线程访问同步代码块时,它首先是需要得到锁才能执行同步代码,当退出或者抛出异常时必须要释放锁。 底层实现 如何来实现这个机制呢?我们先看如下一段简单代码: public class SynchronizedTest{ public synchronized void test1(){ } public void test2(){ synchronized(this){ } } public static void main(String []args){ } } 利用javap工具查看生成的class 文件信息来分析synchronize的实现   从上图可以看出,同步代码块是使用monitorenter和monitorexit指令实现的,同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。    在java语言中存在两种内建的synchronized语法:1、synchronized语句;2

重排序

情到浓时终转凉″ 提交于 2020-02-15 00:21:57
1.Java平台的编译器: Java平台有两种编译器:javac(静态编译器)和JIT(动态编译器)。 javac 将源代码文件编译成字节码文件,在代码编译阶段介入 JIT 将字节码动态编译为Java虚拟机宿主机的机器码,在Java程序运行过程中介入 zzz 来源: https://www.cnblogs.com/i-hard-working/p/12310269.html

JVM原理与内存模型

北城以北 提交于 2020-02-13 02:20:34
编译型语言:一次性地编译成机器码,生成可执行文件。 解释型语言:使用专门的解释器对源码逐行解释成特定平台的机器码并立即执行的语言。 JVM原理: Java语言既是编译型语言,又是解释型语言:Java源码通过javac命令被编译成.class文件,这种字节码文件不面向任何平台,只面向JVM(Java Virtual Machine);JVM是Java跨平台的关键部分,其向上提供给Java字节码程序的接口完全相同,而向下适应不同平台的接口则互不相同,为特定平台提供特定机器码,使用java命令解释执行。 JDK、JRE、JVM关系: JDK包括Java编译器,JRE和其它工具(如javaDoc、java调试器等);JRE包含JVM、类加载器、大量基础类库等。 内存模型: 1. 堆(Heap) 是Java虚拟机所管理的内存中最大的一块不连续的内存区域,也是被各个线程共享的内存区域,该内存区域存放了对象实例及数组(但不是所有的对象实例都在堆中),以及死亡的还未被回收的对象。其大小通过-Xms(初始值)和-Xmx(最大值)参数设置(都要小于1G),为了避免在运行时频繁调整Heap的大小,通常-Xms与-Xmx的值设成一样。堆内存 = 新生代+老生代(永久代不属于堆内存)。在我们垃圾回收的时候,我们往往将堆内存分成新生代和老生代(大小比例1:2),新生代中由Eden和Survivor0

1、Kotlin语言与开发环境

若如初见. 提交于 2020-02-12 12:10:58
Kotlin 语言最早被设计成运行在JVM(Java 虚拟机)上,使用 Kotlin 编写的程序会被编译成字节码文件,该字节码文件可直接在 JVM 上运行。Kotlin 可以与现有的 Java 语言包保持 100% 的兼容性。 Kotlin 用途 Kotlin 程序可以编译成字节码文件,字节码文件可以直接在 JVM 上运行,因此 Kotlin 非常时刻开发后端应用程序。Kotlin 与现有的 Java 语言包保持完全兼容,它完全可以利用 Java 领域现有的各种技术框架。 Google 官方推荐使用 Kotlin 作为 Android 开发语言,因此 Kotlin 一定会成为以后 Android 开发必备的语言。 Kotlin 程序还可以编译成 JavaScript 代码,Kotlin即可以生成前端使用的 JavaScript 代码,也可以生成后端使用的 JavaScript 代码。 使用命令行编译、运行 Kotlin 下载和安装 Kotlin 的 SDK 到 这里 下载和安装 Kotlin 的 SDK,下图展示了页面, Kotlin SDK 的最新版本都会发布到该页面。 点击下方 kotlin-compiler-1.3.61.zip 下载压缩包文件。 将该压缩包文件解压到任意目录下,可以看到如下文件路径。 bin :该路径存放了 Kotlin SDK 的各种工具命令,常用的

JVM之---Java源码编译机制

空扰寡人 提交于 2020-02-12 08:45:46
Sun JDK中采用javac将Java源码编译为class文件,这个过程包含三个步骤: 1.分析和输入到符号表(Parse and Enter) Parse过程所做的工作有词法和语法分析。词法分析要完成将代码字符串转变为Token序列。语法分析则是根据语法将Token序列生成抽象语法树。 Enter过程将符号输入到符号表,通常包括确定类的超类型和接口、根据需要添加默认构造器、将类中出现的符号输入类自身的符号表中等。 2.注解处理(Annotation Processing) 该步骤主要用于处理用户自定义的annotation,可能带来的好处是基于annotation来生成附加的代码或进行一些特殊的检查,从而节省一些共同的代码的编写。此功能基于JSR269,在Sun JDK6 中提供了支持,在注解处理完之后,再次进入上一步骤。 3.语义分析和生成class文件(Analyse and Generate) 该步骤基于抽象语法树进行一系列的语义分析,包括将语法树中的名字、表达式等元素与变量、方法、类型等联系在一起;检查变量使用前是否已声明;推导泛型方法的类型参数;检查类型匹配性;进行常量折叠;检查所有语句都可到达;检查所有checked exception 都被捕获或抛出;检查变量的确定性赋值(例如有返回值的方法必须确定有返回值);检查变量的确定性不重复赋值

Lua加密

自闭症网瘾萝莉.ら 提交于 2020-02-12 02:49:59
两种方式:一种用luac,一种用luajit luac加密: 1、lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,去官网下载Lua源代码包(http://www.lua.org/ftp/),下好解压,目录如下 2、启动一个Visual Studio 命令行工具,用32位命令行会生成32位版本,用64位则生成64位版本 3、在命令行中使用cd 进入lua目录(刚才解压后的目录),然后输入 "etc\luavs.bat" 回车 4、如果没有问题的话,会显示生成过程,(64位下还会有几个warning C4334)、完成后会在src目录下找到生成结果,4个主要文件一个.exp的中间文件,luac.exe生成完毕, 然后把luac.exe所在存在的目录设为环境变量,如果不设置的话,那么执行生成字节码的dos命令的时候就要转到luac.exe所在的目录才能执行此dos命令了,都懂得,不多说 5、(1)、新建一个名为1.lua的文件,里面只有一句话print("Hello Lua"),新建一个空的out.lua脚本文件 (2)、开始--运行--cmd (3)、luac -o out.lua 1.lua 注: luac - o [编译后脚本名] [脚本名],必要时带上脚本路径,如: 然后实验一下,执行这个字节码脚本

day25_Junit测试丶反射丶注解

隐身守侯 提交于 2020-02-11 22:36:40
软件测试 查询百度百科: 软件测试(英语: Software Testing ),描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。换句话说,软件测试是一种实际输出与预期输出之间的审核或者比较 过程 。软件测试的经典定义是:在规定的条件下对程序进行 操作 ,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。 测试的分类 黑盒测试: 不需要写代码,给输入值,看程序是否能够输出期望的值。 白盒测试: 需要写代码的。关注程序具体的执行流程。Junit测试属于白盒测试中的一种。 现在我们拿到一个需求,需要测试一下Junit包下的Calculator类代码编写是否正确。代码如下 package Junit; /** * 计算器类 */ public class Calculator { /** * 加法 * @param a * @param b * @return */ public int add(int a, int b){ return a +b; } /** * * @param a * @param b * @return */ public int sub(int a,int b){ return a -b; } } 按照以前的知识,我们需要在测试类中,创建Calculator类的对象,在调用Calculator类中编写的方法