我也想从零开始了解一下JVM虚拟机

从零开始掌握 JVM JVM是Java设计者用于屏蔽多平台差异,基于操作系统之上的一个"小型虚拟机",正是因为JVM的存在,使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次生成class字节码,即可在任何操作系统都可以以相同的方式运行。类加载器实现将编译后的class文件加载到内存,并转为为运行时区域划分的运行时数据结构,注意类加载器只能决定类的加载,至于能不能运行则是由来决定。 阅读详情

微信公众号:Java患者
专注Java领域技术分享

启动JVM

编写一个最简单的HelloWorld类,然后运行:

public class HelloWorld {
  
  public static void main (String[] args) throws Exception{
    System.out.println("HelloWorld");
    Thread.sleep(10000);
  }
}

启动一个虚拟机(图1)

采用最原始的方式运行Java文件,打开任务管理器我们可以看到一个java.exe,是的,这个就是Java虚拟机,当10秒过后,main方法执行结束,java.exe结束,虚拟机结束,所以当我们启动一个java的main方法的时候我们就启动了Java虚拟机。

接着我们同时运行两次HelloWorld这个java类。同时就出现了两个java.exe,没错,运行了两个main方法,所以同时启动了两个Java虚拟机。

启动两个虚拟机(图2)

具体来说就是运行了几个main方法就启动了几个java应用,也就启动了几个虚拟机,到这里我们先认识了java虚拟机究竟是个什么玩意。

Java跨平台

当我们编写了一个HelloWorld.java文件之后,我们进行编译成class文件

Java文件编译(图3)

接着我们只需要把class文件放到机器上就可以运行,比如window或者linux。

class文件转为机器码(图4)

那么这个时候JVM就是将我们的class文件加载了之后(怎么加载?)丢到了机器识别的二进制然后进行运行。

虚拟机充当的角色(图5)

那么在这里因为是一次编写到处运行,那么这个时候我们就会下载不同的jdk,不同的机器识别的指令是不一样的,所以我们需要安装不同的jdk,以使用我们不同的JVM去加载同一个class文件,然后丢到不同的机器上去运行。

jvm的跨平台(图6)

JVM的生命周期

package com.zero;

public class jvm_01 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.currentThread().sleep(i*10000);
                        System.out.println("我是Thread线程" + i*10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("我是main方法的" + i);
        }
    }
}

运行该程序,然后启动任务管理器查看

运行截图(图7)

当main方法for循环打印结束后,虚拟机还没有退出,而是等到Thread这个线程运行完之后才退出虚拟机,因为在虚拟机中有两种线程,分别是守护线程和非守护线程,main方法是属于非守护线程,在虚拟机中,只要有非守护线程未结束,虚拟机都不会退出,由于mian方法中启动了一个匿名线程也是一个非守护线程,所以它没有结束虚拟机也不会结束。而垃圾回收线程就是守护线程,守护线程是会自动销毁的,当虚拟机中的非守护线程全部退出之后,守护线程也就自动销毁。

非守护线程可以当做是象棋中的将军,守护线程则是象棋中将军旁边的守护者,当将军死了之后,守护者就没有存在的必要了,自然就自己销毁了。

JVM内存

在了解JVM虚拟机内存之前,我们先了解一下操作系统的内存。

操作系统中的内存分布(图8)

首先我们了解到操作系统的内存是这样分布的,而JVM内存就是存在于我们的操作系统中的内存的一部分。

JVM内存(图9)

JVM内存是放在操作系统中的堆内存中,操作系统中的栈内存是由操作系统管理的,而堆内存一般是由我们去管理的,所以JVM的内存应该放在了操作系统的堆中,方便我们自己管理。

接着我们了解JVM内存结构。

JVM内存结构(图10)

我们可以发现JVM的内存结构跟操作系统中的内存结构似乎一致?原来JVM的设计模型其实就是操作系统的设计模型了,在基于操作系统的角度,JVM实际上就是一个应用,一个线程。但是基于class文件来讲,JVM就是操作系统,而JVM内存结构中的方法区,在class文件看来,就是一块“硬盘内存”。

所以概括的说,JVM内存主要分 堆(heap)、栈(stack)、方法区。

(图11)

栈内存分为了虚拟机栈跟本地方法栈

堆内存分为了新生代跟老年代,新生代分为了Eden区,From Survivor区、To Survivor区。

JVM运行时数据区

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。图如下,如何理解划分?

简单来说就是当你喝一口水下去之后,水就分散到了各个器官比如肾、胃、肝等等 这些就好比于运行时数据区。

(图12)

程序计数器:当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,大概就是一个计数器,里面存了下一次要执行哪一行代码。

并且由于Java虚拟机的多线程时通过线程轮流切换、分配处理器执行时间的方式来实现。那么为了线程切换后可以恢复到正确的执行位置,每条线程都必须要有一个单独的程序计数器,所以它属于一块线程私有的内存。

简单来说:有两个线程A,B同时执行这个class,那么线程A的程序计数器执行到了第9行,就会记录10,以便下一次执行,刚好线程B进来了,要执行第一行,那么线程B的计数器就是1,执行完线程B之后可能执行线程A,这个时候就知道线程A要执行到了第10行。

如果此时线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码的指令的地址。

Java虚拟机栈:虚拟机栈描述的是Java方法执行的时候的线程内存模型,每个方法在被执行的时候,Java虚拟机都会创建一个栈帧,这个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。

Java虚拟机以方法作为最基本的执行单元,“栈帧”则是用于支持虚拟机进行方法调用和方法执行背后的一种数据结构。其存储了方法的局部变量表、操作数栈、动态连接、方法返回地址和一些额外的附加信息。

栈帧的概念结构(图13)
  • 局部变量表:一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。局部变量表的容量是以变量槽为最小单位的,一个变量槽可以存放一个32位以内的数据类型,也就是说每个槽基本应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据,当然reference类型表示的是一个对象的引用地址,在这并没有很明确的指出这种引用是怎么样的数据结构。

    对于64位的数据类型,比如long类型以及double类型,Java虚拟机是以高位对齐的方式为其分配两个连续的变量槽空间的。

    接着我们了解Java虚拟机是如何使用局部变量表的。Java虚拟机通过索引定位的方式来使用局部变量表,索引值的范围就是从0开始一直到局部变量表最大的变量槽数量,假设有10个int类型的数值,索引就是从0到9,如果访问的是32位数据类型的变量,索引值就是N,如果访问的是64位数据类型的值,索引值会同时使用N跟N+1。并且对于两个相邻的共同存放一个64位数据类型的两个变量槽,虚拟机时不允许单独访问其中的某一个的。

  • 操作数栈:一个数据运算的地方,大多数指令都在操作数栈运算,然后压栈。当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入跟提取内容,也就是入栈跟出栈操作。

  • 动态连接:在每个栈帧中都会包含一个该栈帧所属方法的引用,这个引用会指向运行时常量池,这个引用的目的是为了方法调用过程中的动态连接

  • 方法返回地址:方法退出之后栈帧的顶端都应该是当前退出方法的上层方法,上层方法的状态会随着本次方法的返回结果而改变,而方法返回地址这块区域就是为了用来帮助栈帧去恢复上层方法的状态。简单点:A方法调B方法,B方法在A方法上面,B方法执行结束,要去找A,并告诉他结果。

本地方法栈

跟虚拟机栈差不多,虚拟机栈服务的是JVM执行的java方法,本地方法栈服务的对象是JVM执行的native方法。其实也是一个方法,只是这个方法可能是用c语言或者其他语言写的…….比如这种鬼东西?

本地方法栈(图14)

方法区

一个用于存储已经被虚拟机加载的类型信息、常量、静态变量、代码缓存等数据。

heap堆

虚拟机内存中最大的一块了,也是一块所有线程共享的一块内存区域,在虚拟机启动时创建,几乎所有的对象创建都存储在堆里面了。当然Java堆就是垃圾收集器管理的内存区域。

对象的创建

Java堆(图15)

我们重点研究虚拟机中堆的知识点,首先要了解java对象的创建,我们都知道Java对象创建之后会分配到我们堆内存中的Eden区域中,那么对象所需的内存大小在类加载完成后就可以确定了,对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据和对齐填充。

那么对象的对象头就包括两类信息

  • 第一类是用于存储对象自身的运行时数据,比如哈希码、GC分代年龄。。。。。。等等,不说太多。这部分数据的长度在32位和64位的虚拟机中分别为32bit跟64bit。对象头

  • 第二类时类型指针,即对象指向它的类型元数据的指针,干什么用的?Java虚拟机通过这个指针确定该对象是哪个类的实例。

实例数据部分存储的是对象的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的或者是子类中定义的字段。

对象的第三部分是对齐填充,并不是必然存在,也没有特别的含义,仅仅起着占位符的作用。这是因为虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,所以如果对象实例数据部分不是8的整数倍,那就第三部分来凑一下。。。

现在知道了对象的大小,就可以给对象分配内存空间了,给对象分配内存空间,其实就是在堆中划分出一块已经确定大小的内存块。

未分配内存(图16)

假设我们现在Eden区域有10M内存,并且在堆中的内存是绝对规整的(被使用的放在一边,已使用的放在另一边),如上图,如果现在内存中并没有对象,那么就会有一个指针指着起始位置。当给对象分配内存的时候(假设内存1M),那么指针就会移动一段与对象的大小相等距离。

图(17)

这种分配方式就称为指针碰撞。

但如果Java堆中的内存并不是规整的,已被使用的内存和空闲的内存是相互交错的,那就没办法用指针碰撞的方式分配内存,那么虚拟机就必须维护一个列表,记录哪些内存块是可用的,在分配的时候从列表中找出一块足够大的空间划分给此次创建的对象的大小,并且更新列表的记录,这种分配方式被称为空闲列表。而选择哪种分配方式是由堆内存是否规整决定的,而堆内存是否完整又由所采用的垃圾回收器是否带有空间压缩整理的能力决定。

当然在分配内存的时候也会出现一个问题,在并发的情况下似乎并不是安全的。什么意思呢?假设我们现在使用指针碰撞的方式分配内存,线程A创建了一个对象是1M,在指针还来不及挪动指针去分配内存的时候,线程B也创建了一个对象,原来的指针又被使用来分配内存。

至于如何解决

  • 方案一:对分配内存空间的动作进行同步处理,性能较差

  • 方案二:把内存分配的动作按照线程划分在不同的空间之中进行,也就是每个线程在堆中预先分配一小块内存,这种称为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有当本地缓冲区用完了,分配新的缓存区时才需要同步锁定。

分代

我们都知道在新生代实行了分代,分别是Eden区,From Survivor(S0),To Survivor(S1),并且他们所占的比例是8:1:1,那么为什么要分代呢?其本质在于对象的生命周期不一样,所以要分代。因为98%的对象在minor GC的时候会被回收掉,什么是minor GC呢?创建的对象都会分配到Eden内存,当Eden内存不够的时候,就会触发一次minor GC,这个时候就会有98%的对象被回收掉,存活的会进入S0内存或者S1内存,S0跟S1总是有一块区域是空闲的,因此新生代实际可用的内存空间为90%的新生代空间。

在经过一次Minor GC之后,使用复制算法将这些仍然存活的对象复制到另外一块Survivor中,然后清理使用的Eden区域跟Survivor,并且将对象的年龄+1,当对象的年龄达到某个值时,这些对象就会进入老年代,当然对于一些较大的对象则时直接进入老年代。

专注分享Java技术,跟我一起学习吧

长按识别二维码关注

【从零开始学习JVM | 第一篇】快速了解JVM 在探索现代软件开发的丰富生态系统时,我们不可避免地会遇到一个强大而神秘的存在——Java虚拟机(JVM)。作为Java语言最核心的组成之一,JVM已经超越了其最初的设计目标,成为一个多语言的运行平台,支撑着企业级应用、大数据处理、移动应用等众多领域的技术栈。JVM的独特之处在于它的架构设计,它不仅负责代码的执行,还包括了内存管理、垃圾回收、线程同步等高级功能,这些都是确保高效、稳定运行Java程序的关键因素。 阅读详情

相关推荐

【从零开始学习JVM | 第六篇】快速了解 直接内存

当谈及Java虚拟机(JVM)的内存管理时,我们通常会想到堆内存和栈内存。然而,还有一种被称为"直接内存"的特殊内存区域,它在Java应用程序中起着重要的作用。直接内存提供了一种与Java堆内存和本地内存进行交互的方式,同时也为我们提供了更高效的内存管理手段。在本文中,我们将深入探讨JVM直接内存的概念、工作原理和使用场景。我们将介绍直接内存与Java堆内存的对比,探讨其中的异同点。此外,我们还将探讨如何使用Java NIO库来操作直接内存,以及如何通过合理的使用直接内存来提升应用程序的性能。目录。

fckbb的博客 3090

自己动手写Java虚拟机 (Java核心技术系列)_java版

序   有一本用go语言编写的《自己动手写Java虚拟机》的书籍,抛开性能不说,但这本书已经勾勒出虚拟机的模型,对于想真正了解虚拟机执行原理的小伙伴,无疑是雪中送炭,有人会说,我不如直接去研究真正的Java虚拟机,那才叫原汁原味,学习概念模型的虚拟机和真实的虚拟机肯定是有巨大差别的, 但是我想说,如果你真这么牛逼,也不需要看我的博客了,我个人觉得,人的能力精力是有限的,如果花较少的时间和精力,就能对虚拟机有一个大致的了解,等将来有能力,精力,毅力再去研究jdk源码的实现,不失为一种曲线救国的办法,首先,我对

黄裳博客 2633

《自己动手写Java虚拟机》的源代码实现,使用Go语言构建Java虚拟机。.zip

《自己动手写Java虚拟机》的源代码实现,使用Go语言构建Java虚拟机。

自己动手写java虚拟机(第一话)

使用go语言,自己手写一个java虚拟机,体验造物主的赶脚~

高山仰止,景行行止 1306

VS2019手动添加bits/stdc++.h全指南(附解决‘无法打开源文件‘错误)

本文详细介绍了在Visual Studio 2019中手动配置C++万能头文件bits/stdc++.h的完整方法,解决常见的'无法打开源文件'错误。通过分析GCC与MSVC编译器生态差异,提供了纯手动创建和MinGW移植两种可靠方案,并给出详细的步骤、常见错误排查及最佳实践建议,帮助开发者高效配置竞赛开发环境。

weixin_29011395的博客 545

图像去雾常见数据集

上述数据集涵盖了室内、室外、真实和合成等多种场景,可以满足不同研究需求。在选择数据集时,建议根据具体任务的应用场景和目标选择合适的数据集,例如真实雾天图像适合模型的实际应用验证,而合成数据则适合模型的快速迭代和训练。希望本文能为从事图像去雾研究的朋友提供一些帮助!

m0_68604571的博客 6333

【JVM】手写Java虚拟机-01 命令行工具

介绍 手写一个简单的Java虚拟机,参考了bugstack虫洞栈,声哥,《自己动手写Java虚拟机》,和JVM-Demo。 本系列文章尽可能按照保姆级呈现。 如果有任何问题和建议,请联系我。 环境 操作系统:Windows 10 IDE:IntelliJ IDEA 2019.1 x64 JDK:Java 11.0.8 项目管理工具:apache-maven-3.5.4 [下载] 配置环境 Java的安装网上很多教程,就不赘述了。 注意安装Maven时,解压好之后要修改系统路径。然后试试调用cmd的mvn -

锥栗的博客 1084

EDKII实战:手把手调试PciHostBridge.c,看UEFI如何分配你的PCIe设备资源(IO/Memory空间)

本文深入解析EDKII中PciHostBridge.c模块的工作原理,详细指导如何调试PCIe设备资源分配(IO/Memory空间)。通过实战案例展示UEFI环境下Root Bridge初始化、地址空间转换及协议安装等核心流程,提供常见问题排查方法与性能优化建议,帮助开发者解决PCIe设备兼容性问题。

weixin_29201933的博客 208

自己动手java虚拟机_自己动手写Java虚拟机

目  录前言第章 命令行工具1.1 准备工作1.1.1 安装1.1.2 安装1.1.3 创建目录结构1.2 命令1.3 编写命令行工具1.4 测试本章代码1.5 本章小结第章 搜索文件2.1 类路径2.2 准备工作2.3 实现类路径2.3.1 接口2.3.22.3.32.3.42.3.52.3.62.4 测试本章代码2.5 本章小结第章 解析文件3.1 文件3.2 解析文件3.2.1 读取数据3....

weixin_31865183的博客 463

Android双目摄像头(RGB+IR)实时预览与人脸活体检测实战指南

本文详细介绍了Android双目摄像头(RGB+IR)实时预览与人脸活体检测的实战指南。通过双摄同步预览、人脸检测与活体判断等技术实现,提升安全认证的准确性和鲁棒性。文章还提供了开发环境搭建、常见问题解决方案及性能优化建议,帮助开发者快速掌握双目摄像头在Android平台的应用。

vulkan6gpu的博客 686

“三进制”bonsai27b+NInfer=6g显存闪电侠(token真的自由了!)

本文将1.58-bit三元大模型Bonsai27B成功移植至NInfer推理引擎,并在RTX 4080 SUPER上实现100+ token/s的极速推理。通过自研补丁扩展NInfer支持Ada架构与三元量化格式,解决激活布局、行置换等关键bug,实测PPL 6.445,单流吞吐达96.7–130.8 t/s,20题基准得分16/20。附完整复现包(含文档、工具、源码补丁),零权重分发,助力垃圾显卡跑通27B级模型。

shensanshu的博客 1万+

动手写java虚拟机_[JVM] - 一份<自己动手写Java虚拟机>的测试版

配置GOROOT(一般是自动的),配置GOPATH(如果想自己改的话)参照> 第一章 指令集和解释器生成了ch01.exe文件这里还生成了一个gopkgs.exe文件执行以上操作,这里说明:go开发java虚拟机实际上这段模拟的是命令行在安装好java JDK后的一些输入,比如查看java的version信息.这里已经在代码中写好了.main.go :package mainimport "...

weixin_42395725的博客 409

如何用Python+Librosa实现轴承异响检测?5步搞定工业设备故障预警

本文详细介绍了如何利用Python和Librosa库,通过5个步骤构建工业轴承异响检测与故障预警系统。从音频采集、预处理、频谱特征提取,到构建机器学习模型并进行实时监测,提供了完整的代码级解决方案。该方法能有效识别轴承早期故障特征,实现低成本、高效的设备预测性维护。

rnn9storyteller的博客 631

我也想从零开始学JVM虚拟机

启动JVM 编写一个最简单的HelloWorld类,然后运行: public class HelloWorld { public static void main (String[] args) throws Exception{ System.out.println("HelloWorld"); Thread.sleep(10000); } } 采用最原始的方式运行Java文件,打开任务管理器我们可以看到一个java.exe,是的,这个就是Java虚拟机,当10秒过后,m

ZeJava的博客 383

408 | 408常用计算公式与方法 —— 计组篇 汇总

408常用计算公式与方法 —— 计算机组成原理篇 汇总

"You are worthy! You can do it!" 4649

SAP 系统间 SSO 的真正价值,从 SM59 到可信 RFC 的安全设计

SAP S/4HANA系统间Single Sign-On(SSO)的核心价值在于集中管理通信身份与信任关系,而非仅减少密码输入。传统固定账号密码方式在系统规模扩大后会面临密码管理、审计追踪等挑战。通过SM59配置可信RFC目标系统,结合SSL证书或SAP Trusted System等强认证机制,能有效降低安全凭据暴露风险。SSO配置需配合授权对象、角色管理等建立清晰的信任边界,实现系统间安全通信的同时保持可审计性。这种方案特别适用于Fiori前端与S/4HANA后端等场景,通过可信RFC传递用户身份,避免

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1060

【JVM】从零开始深度解析JVM

本篇博客给大家带来的是JVM的知识点, 重点在类加载和垃圾回收机制上.🐎文章专栏: JavaEE初阶🚀若有问题 评论区见❤如果你不知道分享给谁,那就分享给薯条.你们的支持是我不断创作的动力 .王子,公主请阅🚀1. JVM简介1.2 Taobao JVM(国产研发)1.3 JDK JRE JVM三者关系(经典面试题)2. JVM 运行流程★3. JVM运行时数据区(内存区域)3.1 堆(线程共享)3.2 Java虚拟机栈(线程私有)/本地方法栈。

薯条不要番茄酱的博客 3779

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

从零开始学JVM:Java虚拟机入门指南

想象你写了一封中文信,需要让全世界的人都能看懂。这时你需要一个翻译,把中文翻译成英文、法文、日文等。JVM(Java 虚拟机)就是这样的翻译官,它把 Java 代码翻译成不同计算机能理解的语言,实现 "一次编写,到处运行"。 3. 本地方法栈(调用外部资源的 "翻译官") 作用:让 Java 调用 C/C++ 等本地代码 常见场景:操作硬件、数据库连接(如 JDBC) 4. 堆(对象的 "大型仓库")

小高的博客 912

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【从零开始学习JVM | 第五篇】快速了解运行时数据区

当谈论 Java 程序的运行机制时,JVM(Java 虚拟机)的运行时数据区是一个必不可少的话题。JVM 运行时数据区是 Java 程序在运行过程中分配内存和管理数据的重要区域,它包括了方法区、堆、虚拟机栈、程序计数器和本地方法栈等部分。了解 JVM 运行时数据区不仅有助于理解 Java 程序的运行原理,还有助于优化程序的性能和解决一些与内存管理相关的问题。本文将从各个方面介绍 JVM 运行时数据区的结构和作用,希望能够为读者提供全面深入的了解。

fckbb的博客 3490

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

写给小白的JVM学习指南

点击上方关注我,选择“置顶或者星标”Java 虚拟机是学习 Java 的基础,也是迈入高级 Java 开发工程师的必备知识点。所以今天这篇文章我们来聊聊如何从零开始学习 ...

陈树义 383

从零开始,自己动手写Java虚拟机

从零开始,自己动手写Java虚拟机 自己动手写一个Java虚拟机 java虚拟机的作用 java虚拟机的组成 java虚拟机的开发 java虚拟机的测试

karizhang的专栏 1万+

从零开始带你成为JVM实战高手!

34个生产案例,还原真实JVM问题现场,阿里资深技术专家带你从零开始成为JVM实战高手!扫描下方二维码即刻了解专栏详情!从零开始带你成为JVM实战高手详细目录 ...

石杉的架构笔记 5621

三.从零开始JVM实战高手-JVM的内存结构

目前市面上已有太多的JVM相关教程和书籍,但是大部分偏理论,比较枯燥难懂,少有结合实际业务开发,站在项目开发的视角下去分析和讲解相关经验的教程;而本套教程会从零开始带着大家一步一步深入了解JVM底层原理,以及结合一些开发中的典型生产环境问题来进行实战剖析,并且几乎采用一步一图的方式进行讲解。通过核心理论和实战案例的结合,希望能对大家对JVM的理解和应用更上一层楼。

墨家巨子@俏如来 964

从零开始学习JVM(一)--初识Java虚拟机

初步认识虚拟机与Java虚拟机

huangjhai的博客 606
上一篇: Swagger和Wired
下一篇: HTTP向HTTPS演化的过程
新时代Java农民工
博客等级 码龄7年 16粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值