本地线程

记一次OutOfMemoryError: unable to create new native thread

蹲街弑〆低调 提交于 2020-02-09 23:12:49
前言 今天在测试环境跑测试用例的时候发现一大片测试用例无法通过,查看日志发现 OutOfMemoryError: unable to create new native thread 。从日志信息来看,很明显,内存不足,无法创建本地线程。 遇到这个异常还是很意外的,测试用例大概就1.5k个,不至于跑个用例就来这么个异常,测试环境当时jvm的内存是4g,感觉不至于出现这个问题。(当然觉得意外的原因还是对jvm线程数量限制的理解有误) 要解决问题,首先,还是的了解jvm的线程数量到底受限哪些因素。 jvm线程数量限制 jvm线程受限于操作系统可用内存还是JVM的内存 1. Java线程的实现是基于底层系统的线程机制来实现的 ,程序中开的线程并不全部取决于JVM虚拟机栈,而是取决于CPU,操作系统,其他进程,Java的版本。JVM的线程与计算机本身性能相关。 这个很重要,不了解这一点,很容易像我之前一样误解为jvm线程个数首先于jvm的内存大小。 JVM线程的栈在64位Linux操作系统上的默认大小是多少 不显式设置-Xss或- XX:ThreadStackSize 时,在Linux x64上 ThreadStackSize 的默认值就是1024KB,给Java线程创建栈会用这个参数指定的大小。这是前一块代码的意思。如果把- Xss 或者 -XX:ThreadStackSize 设为0

多图:一文带你入门掌握JVM所有知识点

别说谁变了你拦得住时间么 提交于 2020-02-09 10:45:45
本JVM系列属于本人学习过程当中总结的一些知识点,目的是想让读者更快地掌握JVM相关的知识要点,难免会有所侧重,若想要更加系统更加详细的学习JVM知识,还是需要去阅读专业的书籍和文档。 本文主题内容: JVM 内存区域概览 堆区的空间分配是怎么样?堆溢出的演示 创建一个新对象内存是怎么分配的? 方法区 到 Metaspace 元空间 栈帧是什么?栈帧里有什么?怎么理解? 本地方法栈 程序计数器 Code Cache 是什么? 注:请 区分 JVM内存结构(内存布局) 和 JMM(Java内存模型)这两个不同的概念! 概览 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略 ,保证了 JVM 的高效稳定运行。 上图描述了当前比较经典的Java内存布局。(堆区画小了2333,按理来说应该是最大的区域) 如果按照线程是否共享来分类的话,如下图所示: PS:线程是否共享这点,实际上理解了每块区域的实际用处之后,就很自然而然的就记住了。不需要死记硬背。 下面让我们来了解下各个区域。 一、Heap (堆区) 1.1 堆区的介绍 我们先来说堆。堆是 OOM故障最主要的发生区域。它是内存区域中最大的一块区域,被所有线程共享,存储着几乎所有的实例对象、数组

Web Worker

痞子三分冷 提交于 2020-02-09 01:24:33
概述 我们都知道JavaScript是一门单线程语言,其单线程带来了很大的不便。Web Worker的出现就是为JavaScript创造多线程的环境,运行主进程创建Worker线程,将一些任务分配给Worker线程运行。主线程运行的同时,Worker线程在后台运行,两者互不干扰。Worker线程计算的结果返回给主线程,这样主线程在面对计算密集型或高延迟的任务,就会比较流畅。 Web Worker的特点 Worker线程一旦创建成功,就会始终运行。即使主线程卡死,它依然在运行。这样有利于与主线程通信,但是这也造成了Worker比较浪费资源,所以,一旦用完,我们就应该关闭它。 同源限制: 分配给Worker线程运行的脚本文件,必须与主线程的脚本文件同源 DOM限制: 不能操作主线程中的DOM,要保持DOM的唯一性。 document 、 window 、 parent 这些对象都无法使用。可以使用 navigator 、 lacation(只读) 、 XMLHttpRequest 、 setTimeout 等API。 脚本限制: Worker线程不能执行 alert()、confirm() 这些方法。但可以使用 XMLHttpRequest 对象发出 AJAX 请求。 文件限制: 不可以读取本地文件(js主线程也不能)。出于安全性考虑,浏览器不允许js读取本地文件。 两类线程: Web

JVM(二)JVM内存布局

痞子三分冷 提交于 2020-02-09 00:16:09
这几天我再次阅读了《深入理解Java虚拟机》之第二章“Java内存区域与内存溢出异常”,同时也参考了一些网上的资料,现在把自己的一些认识和体会记录一下。 (本文为博主原创文章,转载请注明出处) 一、概述 在网上看到很多的各种文章来写Java内存布局/Java内存模型(JMM)/Java内存分配和回收等。初学者,往往容易被搞混淆,这些东西到底都是些啥?讲的是不是同一个东西?如果不是同一个东西,那它们之间又有什么区别和联系?说句实话,笔者在看到这些文章和概念时,一样是有这些疑问的。下面我来说说我的理解,如果有人觉得有异议或者不对的地方,欢迎讨论和指出,谢谢! 1.1 Java内存布局 我认为这是一个静态的概念, 即JVM在概念和作用上对其管理的内存进行划分。如整体上来看,JVM的内存分为堆区和非堆区,而非堆区又包括了方法区、JVM栈、本地方法栈、程序计数器等。直接上图: 图1.1 1.2 Java内存模型(JMM) 这个讲的是Java多线程的情况下,多线程之间的内存通信模型。即如果多个线程存在共享同一块内存的情况下,JVM通过一个什么样的内存模型来解决多线程对共享内存的读取和写入数据的问题。借用网上的一张图: 图1.2 从上图中我们可以看到,JMM的核心思想是把堆中的内存分成了两部分:主内存和本地内存,主内存为所有线程共享,而本地内存则由线程独享,同时,对于共享变量

40个Java多线程问题总结

▼魔方 西西 提交于 2020-02-08 22:14:31
前言 这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也有、也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不吝指教。 1、多线程有什么用? (1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 (2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题

JAVA之内存结构

℡╲_俬逩灬. 提交于 2020-02-08 20:29:21
概述 JAVA是我们现在最常用的开发语言,而他的垃圾回收机制(Garbage Collection)的重要作用不言而喻,以下简称GC,所以了解GC至关重要,现本人对于GC机制以前的理解和现在的理解记录整理一下,供大家参考和指正。 说起GC机制,大部分人都把这项技术当做JAVA语言的伴生物。事实上,GC的历史比JAVA久远的多,比如:1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言,当然本文只讲解JAVA的GC机制。废话到此为止。 除了基础知识的讲解还有本人之前的测试数据和测试日志,JDK的版本是:JDK1.8.0_131。 JVM简介 在JAVA程序中,GC运行在JVM虚拟机中的,所以有必要了解JVM的基础知识; 所有的开发人员在开发运行JAVA程序的时候,都会有这样的困惑,JVM虚拟机是JAVA的核心竞争力,他们的内存结构是什么样的呢?见下图,当然也是本人借鉴网上的: JVM内存结构主要有三大块:堆内存、方法区和栈。而堆内存就是JVM中最大的一块由年轻代和老年代组成,而年轻代又分为三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比列来分配。 方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆)

Java基础-JVM堆与栈

独自空忆成欢 提交于 2020-02-08 15:28:10
首先看一个解析列子 JVM的内存空间: (1). Heap 堆空间:分配对象 new Student() (2). Stack 栈空间:临时变量 Student stu (3).Code 代码区 :类的定义,静态资源 Student.class eg:Student stu = new Student(); //new 在内存的堆空间创建对象 stu.study(); //把对象的地址赋给stu引用变量 上例实现步骤:   a.JVM加载Student.class 到Code区 b.new Student()在堆空间分配空间并创建一个Student实例 c.将此实例的地址赋值给引用stu, 栈空间 java内存分区 运行时数据区即是java内存,而且数据区要存储的东西比较多,如果不对这块内存区域进行划分管理,会显得比较杂乱无章。程序喜欢有规律的东西,最讨厌杂乱无章的东西。   根据存储数据的不同,java内存通常被划分为5个区域: 程序计数器(Program Count Register)、本地方法栈(Native Stack)、方法区(Methon Area)、栈(Stack)、堆(Heap) 。 程序计数器(Program Count Register)   又叫程序寄存器。JVM支持多个线程同时运行,当每一个新线程被创建时,它都将得到它自己的PC寄存器(程序计数器)

Java虚拟机系列一:一文搞懂 JVM 架构和运行时数据区

…衆ロ難τιáo~ 提交于 2020-02-08 12:56:18
前言 之前写博客一直比较随性,主题也很随意,就是想到什么写什么,对什么感兴趣就写什么。虽然写起来无拘无束,自在随意,但也带来了一些问题,每次写完一篇后就要去纠结下一篇到底写什么,看来选择太多也不是好事儿,更重要的是不成体系的内容对读者也不够友好。所以以后的博客尽量按系列来写,不过偶尔也会穿插其他的内容。接下来一段时间我会把写博客的重点放在 JVM (Java Virtual Machine) 和 JUC (java util concurrent ) 上,对 Java 虚拟机和 Java 并发编程进行一系列的介绍,欢迎关注。 了解 JVM 是对 Java 开发人员的基本要求,JVM 的相关内容自然也成了现在 Java 程序员面试的重要考点。不过估计很多小伙伴和我一样,长时间醉心于 CRUD,却忘了去了解一下更底层、更基础的东西,殊不知这些才是决定你能在这条路上走多远的关键因素,那接下来我们就一起来深入学习一下看似神秘的 JVM 吧。JVM 总体来看内容还是很多的,我会把最重要的内容介绍给大家,不过如果你有时间和精力的话,还是推荐你去看一下《深入理解Java虚拟机》这本书,确实是有口皆碑。本系列文章也会引用很多此书的内容并加上我自己的理解,如果你坚持看下去的话,相信会有很大的收获。 首先对 JVM 做个简单的介绍,JVM 是 JDK 的一部分,《Java 虚拟机规范》(The

JVM内存模型

会有一股神秘感。 提交于 2020-02-08 06:16:09
如果想了解JVM内存模型,首先我们要知道JVM是什么?JVM全称 Java Virtual Machine ,即Java虚拟机,是用于运行Java程序编译后的字节码文件。 JVM最常见的三种有:1.Sun公司的 HotSpot,是目前使用最广泛的Java虚拟机。2.BEA公司的 JRockit,后来被 Oracle收购。3.IBM公司的 J9VM。 我们知道,Java的口号是: “Write once, run anywhere”,即一次编写,到处运行。为什么可以做到这样呢,其实就是依赖于JVM。在不同的操作系统上,只要安装了对应的虚拟机,那么同样的一份代码,就可以随意移植。 当编写完Java代码时,即产生 .Java文件,会通过Java编译器编译为.class 文件,然后通过Class Loader把类信息加载到JVM中,最后JVM再去调用操作系统。这样,只要JVM正确执行.class文件,就可以实现跨平台了。 以下即为JVM的内存模型图: 程序计数器: 程序计数器是一块较小的内存,可以看做是当前线程所执行的字节码的行号指示器,即记录当前线程所执行到的字节码的行号。当字节码解释器工作时,就是通过改变计数器的值来选取下一条需要执行的字节码指令。由此来完成分支、循环、跳转、线程恢复、异常处理等功能。 程序计数器是线程私有的(即每个线程拥有一个程序计数器)

Java--基础知识之JVM

走远了吗. 提交于 2020-02-08 01:34:21
一、什么是JVM 1、概念 JVM,即Java Virtual Machine(Java虚拟机),是Java和的核心和基础,是在Java编译器和操作系统平台间的虚拟处理器。JVM是利用软件方法实现的抽象的、计算机基于下层的操作系统和硬件平台可以在上面执行Java程序的字节码程序。 2、特点 JVM有完善的硬件架构(如处理器、堆栈、寄存器),其存在是为了支持与操作系统无关,实现Java跨平台。 3、Java的跨平台性 真正跨平台的是Java程序而非JVM。不同平台下安装了不同版本的JVM。编写的Java源码在编译后生成class文件(字节码文件),JVM是负责将这些字节码文件翻译成特定平台下的机器码然后运行,即在不同平台下安装对应的JVM,就可以运行编写的Java程序。而这个过程中Java程序没有做任何改变,只是通过JVM在不同平台上运行罢了,可以说是“一次编译,多处运行”。 4、启动与消亡 JVM负责运行一个Java程序,当启动一个Java程序时,也产生一个虚拟机实例,当程序关闭时这个虚拟机实例也消亡。 JVM运行起点:Java虚拟机实例通过调用某个初始类的main方法来运行Java程序,这个main方法是共有的、静态的、返回值为void类型,并传入一个字符串数组作为参数。 5、两种线程 (1)守护线程:通常由虚拟机自己使用,比如执行垃圾收集任务的线程