- 博客(21)
- 资源 (1)
- 收藏
- 关注
原创 POI-Excel表格生成速度优化
从实际上看,笔者之前的项目用的Excel表格工具类,是一个单线程的工具类,执行效率比较慢。在生成Sheet,1W行数据时,花费大概在10秒左右,多Sheet数据量叠加,时间开销也会线性叠加。笔者项目用的框架是阿帕奇开源的POI,本篇文章的主体聚焦于优化的思路,如POI的使用、线程池细节、并发工具类的使用等,不在讨论范围。在生产环境,通过以下优化之后,生成Excel的速度能快上好几倍(产品赶紧给我加鸡腿)。分Sheet优化Excel表格中,不同的sheet应该没有什么关联关系,起码对于笔者的
2021-03-19 18:11:06
1770
原创 Java虚拟机—运行时数据区—堆
虚拟机的方法区和堆空间,是每个线程共用的,其他数据区为每个线程私有,私有数据区颗粒度较细,难有优化的空间。而共用的数据区,内存分配时能得到较多的内存,所以该数据区是GC时的重点。堆在JVM启动时被创建,大小也随之确定,是JVM最大、最重要的一块内存空间。堆在物理上不连续,而在逻辑上连续。虽然堆是每个线程共享,但也可以划分线程私有的缓冲区。几乎所有的对象实例和数组都分配在堆中,少部分分配在栈中。对象和数组可能永远不会存储在栈上,栈帧中仅保存引用,而这引用指向堆中的位置。在栈帧结束后,堆中的对象不会马上被移
2020-11-15 23:12:06
142
原创 Java虚拟机—堆的常用参数
-XX:PrintFlagsInitial,查看所有参数的默认初始值-XX:+PrintGCDetails,查看GC的详细处理日志-XX:+PrintGC,查看GC的简要信息-XX:PrintFlagsFinal,查看所有参数的最终值-Xms,初始堆内存的空间-Xmx,最大堆内存的空间-Xmn,新生代默认值及最大值的大小-XX:NewRatio,新生代和老年代在堆重的占比-XX:SurvivorRatio,设置Eden和S区的比例-XX:MaxTen..
2020-11-15 23:10:30
139
原创 Java中的对象都分配在堆中?
Java中的对象可以不分配在堆中,因为还存在栈上分配、同步省略和标量替换三种技术都需要使用逃逸分析逃逸分析,是一种可以有效减少Java程序中同步负载和堆分配压力的跨函数全局数据流分析算法。当一个对象在方法中被定义后,对象只在方法内部使用,则认为没有发生逃逸;如果对象被外部对象引用,则认为发生逃逸。通过逃逸分析,HotSpot编译器能够分析出一个新对象的使用范围,从而决定是否将这个对象分配到堆上。栈上分配栈上分配所指的栈,是Java方法对应的栈帧。没有发生逃逸的对象可能被优化分配到栈上,因为随
2020-11-15 23:07:54
606
原创 Java虚拟机—运行时数据区—本地方法栈
本地方法接口由native修饰的方法就是本地方法。该方法的实现不是由Java编写,用以融合C/C++的程序。在开发过程中,有时需要与外部系统进行交互,JDK提供的接口不足以满足需求,这是本地方法存在的主要原因;另外,操作系统由C语言编写,通过本地方法可以实现与操作系统的交互;JDK的部分功能需要由操作系统底层的函数提供;本地方法栈:虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。本地方法栈,也是线程私有。栈大小可以固定也可以动态扩展,内存溢出方面与虚拟机栈相同。当本地方
2020-11-03 23:20:08
85
原创 Java虚拟机—运行时数据区—虚拟机栈3—栈帧的内部结构
栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据。正在执行的方法对应的栈帧称为当前栈帧。执行引擎的所有字节码指令只针对栈帧进行操作。如果当前栈帧调用了新的方法,那么新的方法对应的栈帧会被创建出来并压入栈中成为新的栈帧。JAVA方法有两种返回函数的方式,一种是正常的函数返回,使用return指令;另一种是抛出异常;不管是哪种方式,都会导致栈帧被弹出。栈帧内部结构局部变量表: 存在于每个线程的每个栈的每个栈帧中,不存在线程安全的问题。定义为一个数字数组,主要用于存储方法参数和定义
2020-11-03 00:08:37
253
原创 Java虚拟机—运行时数据区—PC寄存器(程序计数器)
PC寄存器是对物理的寄存器的抽象模拟,存在于内存中的数据结构,无物理实体,CPU只有把数据装在到寄存器上才能运行。PC寄存器存储指向下一条指令的地址。由执行引擎读取下一条指令。PC寄存器会存储当前线程正在执行的Java方法的JVM指令地址,如果该方法为native方法,则是undefined。该数据区不会OOM。使用PC寄存器存储字节码指令地址有什么用呢?CPU需要不断切换各个线程,在切换回来的时候,需要知道从哪接着开始。JVM字节码解释器需要通过PC寄存器的值来明确下一条该执行什么样的字节
2020-11-02 23:42:51
167
原创 Java虚拟机—运行时数据区—虚拟机栈2—方法的调用
链接方式、方法绑定、(非)虚方法方法的绑定有两种,分别为早期绑定和晚期绑定,静态链接对应早期绑定,动态链接对应晚期绑定。绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程,该过程仅发生一次。静态链接、早期绑定、非虚方法静态链接:当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译器可知,且运行期保持不变时,这种情况将调用方法的符号引用转换为直接引用的过程称之为静态链接。早期绑定:是指被调用的方法如果在编译期可知,且运行期保持不变时,即可将这个方法与所属类型进行绑定。在子类中
2020-11-02 23:16:45
119
原创 Java虚拟机—运行时数据区-虚拟机栈1—栈的基本内容
不同CPU的架构不同,基于寄存器则对CPU的耦合比较高。虚拟机栈的指令集小,方便编译器解释,更容易实现跨平台的特性。但缺点也很明显,性能比寄存器要差很多。栈是运行时的单位,而堆是存储的单位。栈解决程序如何执行,如何处理数据,而堆解决数据怎么放,放哪的问题。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个栈帧,一个栈帧对应一次方法调用。主管JAVA程序的运行,保存方法的局部变量(基本数据类型和对象的引用地址)、部分结果,并参与方法的调用和返回。栈的特点栈是一种快速有效的分配存储方式,访
2020-11-01 23:38:03
93
原创 Java8新特性-日期API(LocalDateTime、Instant、DateTimeFormatter、Duration、TemporalAdjuster)
日期校正器类为TemporalAdjuster,该类是一个接口,而Java8 也提供了其实现的工具,TemporalAdjusters一些的使用方法如下:LocalDateTime now = LocalDateTime.now();System.out.println("当前时间:"+now);System.out.println("下周日:" + now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));System.out.println("下个月
2020-07-08 09:13:03
549
5
原创 基于hexo & github搭建个人博客
一、 安装node.jsNode官网:http://nodejs.cn/download/如果你的电脑原先没有安装git,需要下载安装:https://git-scm.com/downloadsGit配置:git config --global user.name "your name"git config --global user.email "your email"二、安装cnpm安装node是因为node自带了npm包管理工具,但是这个工具软件源在国外,访问速度较慢国内常用的有c
2020-07-06 20:26:45
181
原创 Java8新特性ParallelStream并行流详细说明和注意事项
ParallelStream在之前文章Java8新特性-Stream API中有简单的了解过它的使用如Collection集合可以通过parallelStream()的得到一个并行流Stream<Integer> stream = new ArrayList<Integer>().parallelStream();串行流也可以通过parallel()方法转为并行流Stream<Integer> stream = new ArrayList<Integer&
2020-07-06 15:48:07
3452
原创 Java8新特性-Optional类
该类是一个容器类,表示一个值存在或者不存在常用方法方法名用途Optional.of(T t)生成一个实例,接受的对象不能为nullOptional.empty()生成一个空实例Optional.ofNullable(T t)若t==null,则创建空实例get()获取当前实例,不存在则NPEisPresent()判断是否有值orElse(T t)原先有值,则返回原值,若无,则返回torElseGet(Supplier s)函数式接
2020-06-29 16:34:28
230
原创 Java8新特性-Stream API
Stream不会存储数据Stream不会改变源对象,而是返回一个新的Stream延迟执行(惰性求值)操作,需要结果的时候才执行1、获取流 ——》2、中间计算——》3、终止操作,产生新流注意:Stream流操作,会延迟加载,并且是内部迭代,比一般的迭代操作速度更快获取流Collection集合对象自带两种方式获取流,以ArrayList为例stream(),串行流Stream<Integer> stream = new ArrayList<Integer>()..
2020-06-29 16:33:19
1003
原创 Java8新特性-方法引用和构造器引用
方法引用lambda体中的内容已经有方法实现,可以使用方法引用注意:引用方法的返回值类型需要跟接口的返回值类型一致对象::实例方法名原先的lambda表达式Consumer<String> consumer = (s) -> System.out.println(s);使用方法引用后的lambdaConsumer<String> consumer = System.out::println;类::静态方法名原lambdaBiFunction<
2020-06-29 16:32:17
165
原创 Java8新特性-函数式接口
接口中只有一个抽象方法的接口,成为函数式接口可以使用@FunctionalInterface注解进行修饰,在编码时会有错误提示如:Runnable接口@FunctionalInterfacepublic interface Runnable { public abstract void run();}Java内置四大核心函数式接口函数式接口参数类型返回类型用途消费型:ConsumerTvoid在业务逻辑中消费掉参数供给型:Supplier-
2020-06-29 16:31:18
188
原创 Java8新特性-lambda表达式
速度更快代码更少强大的Stream API便于并行减少NPElambda表达式Java8中引入了新的操作符,->,该操作符叫箭头操作符,lambda操作符,将表达式拆分成左右两部分,左侧为参数,右侧为逻辑代码,即lambda体注意:lambda表达式需要函数式接口的支持,参数的数据类型可以省略,JVM能够自己判断参数类型无参数无返回值如:创建一个线程,并打印信息Runnable run = () -> System.out.println("hello lambda".
2020-06-29 16:30:05
217
原创 gradle配置本地maven仓库
新增环境变量新建一个名为GRADLE_USER_HOME的环境变量,值为本地maven的路径,环境变量的名字为固定写法示例如图:验证修改重启开发环境,如IDEA后,可以在配置中看到如下信息,即说明修改成功...
2020-06-24 23:45:41
821
原创 gradle配置阿里云为中央仓库
新建配置文件在用户目录/.gradle/中新建名为init.gradle的配置文件示例路径如下:C:\Users\lwx\.gradle\init.gradle添加内容新建完成之后,往该文件中加入如下信息,即可完成配置allprojects { repositories { def ALIYUN_REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public'def ALIYUN_JCENTER
2020-06-24 23:43:14
996
原创 DockerFile命令说明
镜像的构建文件通过build构建成新的镜像如:将myfile文件构建成新镜像myfileFROM centosCMD echo "==========run success==========="CMD /bin/bashbuilddocker build -f ./myfile.txt -t lwx/mycentos .注意:指定必须为大写字母,且后面不能为空从上到下顺序执行# 表示注释每条指定都会创建一个新的镜像层并进行提交DockerFile的运行流程1、
2020-06-24 23:41:17
134
原创 Docker入门指南
docker基础容器、镜像、仓库安装过程以CentOS7为例先更新一下镜像源sudo yum update安装dockersudo yum install docker镜像配置https://cr.console.aliyun.com/cn-shenzhen/instances/mirrors 进入该网站,注册阿里云账号,获得镜像服务的地址,如:https://itweixiang.mirror.aliyuncs.com获取该地址后,进行docker的镜像配置sudo tee
2020-06-24 23:40:33
177
最好用的国产SSH客户端工具FinalShell
2020-07-03
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人