5 我是土堆

尚未进行身份认证

我要认证

公众号:土堆碎念; 一个不焦虑、有趣的公众号! 他有一个百宝袋,能帮你拥有更多的自由时间。

等级
TA的排名 6w+

Spring 概述

在学习 Spring 的时候,我们必须得有个整体性的概念。这个概念就是:Spring 到底是什么?官网给了如下的介绍:The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.A key element of Spring is

2020-07-01 15:12:05

Java 虚拟机栈

栈结构栈,这种数据结构,太重要了。如果学习过算法,就可以了解它的强大了。栈,就像我们叠起来的盘子,只能对最上面的部分进行操作。对于栈,只有两种操作:入栈,在上面再加一个盘子出栈,拿掉最上面的盘子别小看这两种操作,他可以完成很多复杂的事情,这就是数据结构和算法的魅力。JVM 的运行是基于栈的指令集,也就是说,JVM 对于数据的操作,都是基于栈这种数据结构的。栈指令集我们写一段代码:package runningDate;public class JavaStackTest {

2020-06-24 16:19:01

程序计数器

程序计数器先来看这张图,对于数据区,存在着线程,进程的概念。程序计数器是每个线程私有的。如果没有多线程的概念,可以直接无视。程序计数器程序计数器,也有人叫它 程序寄存器。但是叫做 程序计数器更为精确。因为我们知道,在计算机也有一种结构叫做 寄存器,它储存容量小,但是速度快,一般用于 CPU 中。但是我们这里的 程序计数器 只是我们常说的内存中划分出的一块小内存区域,用来充当 程序计数器的功能。它记录了,我们下一条要运行指令的地址。我们来看这张图。右边是我们从 Java 文件编译出的 cl

2020-06-24 15:19:49

运行时数据区

按理说,在介绍完前端编译器之后,我们应该介绍如何让 JVM 去解释运行 这个编译后的 .class 文件。但是感觉并不是很恰当。如果把 .class 文件比做新购买的家具,那么如果需要把家具摆放到家里,是不是得先了解房子的结构和布局,然后才能将家具进行正确的摆放。我们这里介绍的 运行时数据区 相当于前面提到的 房子结构。运行时数据区,这个名字实在取得太高大上了。其实就是,当我们程序运行的时候,这一块区域主要是负责数据的处理。程序的基本逻辑,无非就是不同的数据进行交互。在这块 数据区 中,有很多不

2020-06-24 14:57:43

前端编译

前端编译的主要作用,是将 我们编写的 .java 文件 编译成 .class 文件,也就是我们常说的 字节码 文件。字节码 文件,里面包含了我们编写的 .java 代码中的运行逻辑,参数 以及 这些参数在内存中的分配。前端编译过程解析与填充符号表注解处理分析与字节码生成总而言之,就是对 .java 文件进行语法分析,根据 .java 文件构建抽象语法树。前端编译结果package methodArea;public class MethodTest { public stat

2020-06-24 14:04:57

方法区概述

方法区概述首先先来说说 方法区 的作用。方法区方法区,是用来存放有关 类、方法 信息的一块逻辑上的区域。也就说,人们想规划出一块区域,用来存储类 方法 相关信息。除此之外,还用来存储常量、静态变量,以及一些代码缓存等数据。想想,这些数据都有什么特点。几乎不变;不怎么依赖于对象,独立。方法区的故事关于方法区,有很多的故事 和 混乱。方法区、永久代、元空间都跟他有着故事。故事的缘由是由历史和部分概念不清晰导致的。我们之前说到,方法区 只是一个逻辑上的概念。具体的实现,叫做 永久代 和 元空

2020-06-24 10:31:27

常见测试堆空间的 JVM 参数

-XX:+PrintFlagsInital 查看所有参数的初始值-XX:+PrintFlagsFinal 查看所有参数的最终值-Xms 设置堆的初始值-Xmx 设置堆的最大值-Xmn 设置新生代的大小-XX:NewRatio 新生代与老年代的比例-XX:SurvivorRatio 设置 Eden 和 Survivor 比例-XX:MaxTenuringThreshold 设置进入老年代的年龄阈值-XX:+PrintGCDetails 打印 垃圾回收 的细节-XX:HandlerPromot

2020-06-23 00:08:24

对象创建与堆

这一节主要介绍对象创建时,在堆中的一些过程。回忆下,我们之前说的,什么时候会发生垃圾回收?除了在一些安全点处也许会发生垃圾回收(只是也许),如果在所需内存不足的情况下,一定会发生垃圾回收。分配堆空间首先通过设置参数,把堆空间设置为 20M,其中 新生代 10M,老年代 10M。参数设置:-Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails结果为:Heap PSYoungGen total 9216K, used 1685K [0x00000007

2020-06-22 23:40:35

对象的内存布局

对象的内存布局创建一个对象,不仅仅是找一块内存区域,然后把对象的值赋值进去那么简单。你想想,当我们 new 一个对象出来的时候,我们可以利用反射获取对象的一些信息。可以通过对象调用其中的一些方法。所以,在内存中,对象不仅仅包含了对象值那么简单,它还包含了更多的信息。这些信息保存在一个名为 对象头 的结构中。对象头一个对象实例,包含了 对象头、实例数据 和 对齐填充。对象头主要保存了这个实例的一些信息,实例数据保存了其中的实例数据。最后的 对齐填充,只是为了单纯填充空间。可以从图上看到,对象头主

2020-06-22 14:54:26

基于分代的堆结构

堆的结构是基于分代理论(垃圾回收)的,这种结构划分,是为了更好地进行垃圾回收。我们将堆分为老年代、新生代。永久代、元空间、堆这几个概念一直比较混乱。但是看到上图,堆的定义只包含 新生代 和 老年代。这一点我们在实际设置 JVM 的参数的时候,你会发现,设置的空间的确只包含 新生代 和 老年代。新生代 和 老年代 是根据对象的生命周期特点来区别的。堆参数的设置接下来,我们来看下 Java 8 中,关于 堆 参数的设置:-Xms:表示堆的起始内存-Xmx:表示堆的最大内存一旦堆需要的空间大于

2020-06-22 12:47:14

强软弱虚引用

强软弱虚,是 Java 中比较主流的四种引用。(多念念,就顺口了)从这四种引用的作用来看(接下来你会看到),引用,与对象的存活密不可分。也许正是因为有了 JVM 的垃圾收集器,才有了这四种引用。我觉得直接看四种引用的概念比较好:强引用;无论何时,只要有强引用关系的对象,都不会被垃圾回收器回收掉,如果内存不足的时候,直接报错软引用:有软引用关系的对象,当内存即将不足的时候,会被垃圾回收器清理掉;弱引用:有弱引用关系的对象,只能活到下一次垃圾回收的时候,也就是,只要发生了一次垃圾回收,那么弱引用关系

2020-06-21 19:05:15

安全点和安全区域

前面介绍了垃圾回收器几个方面的内容:如何标记垃圾如何处理垃圾那么还有什么问题要解决呢?既然是自动垃圾回收,那么自动是什么情况呢?在我看来,自动主要来自两个方面:当我们年轻代、老年代内存不足时,触发某种条件,进行垃圾收集还有一个就是我们接下来说的安全点、安全区域安全点为什么要有安全点呢?在一个程序执行过程中,我们不一定要等到内存不足的时候,再进行垃圾回收整理。如果只是等待到内存不足的时候再进行整理,那么这个时候,就会有大量的垃圾,那么处理起来,要耗费的时间就会增长。所以,为了减

2020-06-21 15:36:09

垃圾回收算法

前面介绍了如何去识别和标记垃圾,现在主要介绍,如何去回收(处理、删除)这些垃圾?你也许会想,找到了直接删掉不就行了吗?恭喜你,已经学会了一个很重要的算法。标记-清除(Mark-Sweep)标记-清除算法,主要分为两个步骤,标记 和 清除。标记,就使用之前说过的 可达性分析算法,即可进行标记。就是我们根据 GC Roots 标记出存活对象,然后将垃圾对象进行清除即可。就是这么简单。但是这种算法主要有如下缺点:会产生大量的内存碎片。内存空间不再连续,对于一些大对象连续的对象结构来说,无非是浪费

2020-06-21 14:02:08

垃圾回收相关算法

这里介绍的垃圾回收相关算法,主要解决的问题:判断哪些内存是垃圾(需要回收的)?常用的两种算法:引用计数可达性分析(GC Root)首先介绍算法前,得定义:如何判断一个对象的死亡?我们一般这样定义:当一个对象不再被任何存活的对象继续引用的时候,这个对象就死亡了。引用计数引用计数算法,是给每一个对象添加一个计数器,当有对象引用它的时候,计数器+1,当有对象取消对它的引用时,计数就会-1。当计数器的值为 0 时,即说明没有对象引用它,也就是这个对象死亡了。这种算法很简单,但是有个

2020-06-21 11:14:07

内存访问全过程

这一篇,是重点!我们将去讲解操作系统根据代码(逻辑)地址去访问真实物理地址的全过程。将把全面几节的东西全部用上,并完全梳理,完善细节。前面讲了分段、分页机制,他们都可以实现,从虚拟地址(地址空间)向物理地址的转换。但是,实际使用过程中,使用的是分段+分页机制,段页结合。段页结合全过程分析(高能)我们现在采用边实验边讲解翻译全过程。写了一段 c 代码,编译,然后在 Linux 0.11 中,进行调试#include <stdio.h>int i = 0x12345678;in

2020-05-10 16:54:40

多级页表与快表

之前页表结构的不足之前的页表结构看起来挺好的呀,有什么问题呢?如果每个页的大小是4k,也就是2的12次方。如果是32位的地址话,也就是说,有2的20次方个页。那么对应到页表,也就说页表应该有2的20次方个项。因为每个项表示的是一个内存地址,也就说一个项的大小是32位,也就是4个字节。这样算下来,对应于一个32位的内存地址,一个页表应该4M大小。看起来还可以接受啊。但注意,每个进程都有一个页表。看下,我的电脑现在有280个进程,也就说如果采用之前的结构,光页表结构就得占用280*4M=1120M,

2020-05-09 16:27:54

分页

前面说到了采用分段技术来进行虚拟地址(地址空间)到物理内存的转换。分段有什么问题?肯定得有不足,才需要提出新的技术来改进。那么我们刚才的分段机制,不是挺好的嘛?有什么问题呢?比如说,我们现在存放一些内容,需要占用 160K 的空间,但是我们来看空间的地址空间,分别是150K和50K,每个段都不足以满足 160 K 的要求,但是两个加起来,的的确确可以满足要求。只使用 分段机制,会造成内存碎片,浪费空间。如何解决呢?针对上面的问题,我们可以想到有下面的一些方法:移动已经使用的内存,把空闲的内

2020-05-09 16:11:48

虚拟内存

背景我们一般把内存看成一块连续的字节数组。我们通过指定地址来访问其中的内容。我们看到图上,0KB-64KB 地址范围内,存放着操作系统。如果现在 A 同学想要写一个程序,它指定代码放在64KB-128KB的位置。现在B同学也写了一个程序,为了避免覆盖A同学程序,需要指定将代码放在128KB以后的位置。这样,就很麻烦了,你需要提前知道其他程序所在的位置,这样写代码就特别痛苦。为此,引入了虚拟内存的概念。地址空间的引入为此,引入了地址空间的概念,或者叫做虚拟地址。现在,对每一个程序,进程,都

2020-05-09 15:22:57

内存分段机制

我们可以写一段简单的c代码(code/memory/segment_1.c):#include <stdio.h>int main(){ int a = 1; printf("Hello, World!"); return 0;}然后将其转为汇编,运行:gcc -S segment_1.c之后会生成一个.s 文件(code/memory/segmen...

2020-05-07 17:37:49

Java vs c++ 字符串 vector ArrayList 迭代器数组比较

字符串Java 和 c++ 都支持字符串,但在使用方面有所区别。初始化,Java 的初始化方式比较简朴,= 后加上字符串即可。c++ 可以在变量后,使用括号进行多次重复或者进行赋值。除此之外,Java 可以两个字面量进行直接连接,而c++ 需要字面量另一边需要有一个字符串变量才可以。取值方式不同,如果想获取字符串中的每一个字符。那么Java 只能用charAt 函数,或者转为char[] ...

2020-03-27 13:33:19

查看更多

勋章 我的勋章
  • 持之以恒
    持之以恒
    授予每个自然月内发布4篇或4篇以上原创或翻译IT博文的用户。不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
  • 勤写标兵Lv4
    勤写标兵Lv4
    授予每个自然周发布9篇以上(包括9篇)原创IT博文的用户。本勋章将于次周周三上午根据用户上周的博文发布情况由系统自动颁发。
  • 学习力
    学习力
    《原力计划【第二季】》第一期主题勋章 ,第一期活动已经结束啦,小伙伴们可以去参加第二期打卡挑战活动获取更多勋章哦。
  • 原力新人
    原力新人
    在《原力计划【第二季】》打卡挑战活动中,成功参与本活动并发布一篇原创文章的博主,即可获得此勋章。