本地线程

Java面试- JVM 内存模型讲解

时间秒杀一切 提交于 2019-12-01 23:57:49
经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发。确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些。 JVM 的重要性 首先你应该知道,运行一个 Java 应用程序,我们必须要先安装 JDK 或者 JRE 。这是因为 Java 应用在编译后会变成字节码,然后通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分。 优点 JVM 不仅承担了 Java 字节码的分析(JIT compiler)和执行(Runtime),同时也内置了自动内存分配管理机制。这个机制可以大大降低手动分配回收机制可能带来的内存泄露和内存溢出风险,使 Java 开发人员不需要关注每个对象的内存分配以及回收,从而更专注于业务本身。 缺点 这个机制在提升 Java 开发效率的同时,也容易使 Java 开发人员过度依赖于自动化,弱化对内存的管理能力,这样系统就很容易发生 JVM 的堆内存异常、垃圾回收(GC)的不合适以及 GC 次数过于频繁等问题,这些都将直接影响到应用服务的性能。 内存模型 JVM 内存模型共分为5个区: 堆(Heap) 、 方法区(Method Area) 、 程序计数器(Program Counter Register) 、 虚拟机栈(VM Stack) 、 本地方法栈(Native Method

《深入理解Java虚拟机》-----第13章 线程安全与锁优化

天大地大妈咪最大 提交于 2019-12-01 22:53:37
概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和解决问题,称为面向过程的编程思想。与此相对的是,面向对象的编程思想是站在现实世界的角度去抽象和解决问题,它把数据和行为都看做是对象的一部分,这样可以让程序员能以符合现实世界的思维方式来编写和组织程序。 面向过程的编程思想极大地提升了现代软件开发的生产效率和软件可以达到的规模,但是现实世界与计算机世界之间不可避免地存在一些差异。例如,人们很难想象现实中的对象在一项工作进行期间,会被不停地中断和切换,对象的属性(数据)可能会在中断期间被修改和变“脏”,而这些事件在计算机世界中则是很正常的事情。有时候,良好的设计原则不得不向现实做出一些让步,我们必须让程序在计算机中正确无误地运行,然后再考虑如何将代码组织得更好,让程序运行得更快。对于这部分的主题“高效并发”来讲,首先需要保证并发的正确性,然后在此基础上实现高效。本章先从如何保证并发的正确性和如何实现线程安全讲起。 线程安全 “线程安全”这个名称,相信稍有经验的程序员都会听说过,甚至在代码编写和走查的时候可能还会经常挂在嘴边,但是如何找到一个不太拗口的概念来定义线程安全却不是一件容易的事情,在Google中搜索它的概念,找到的是类似于

JVM和线程池

别来无恙 提交于 2019-12-01 22:00:31
本文链接:https://blog.csdn.net/liuwenliang_002/article/details/90074283 ———————————————— 版权声明:本文为CSDN博主「30以后的男人」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/liuwenliang_002/article/details/90074283 jvm结构原理,GC工作原理 Jvm结构: Jvm主要包括四个部分: 1、类加载器(ClassLoad) 在JVM启动时或者在类运行时将需要的class加载到JVM中。 类加载时间与过程: 类从被加载到虚拟机内存开始,在到卸载出内存为止,正式生命周期包括了:加载,验证,准备,解析,初始化,使用和卸载7个阶段。其中验证、准备、解析这个三个步骤被统称为连接(linking)。 其中,加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的 ,类的加载过程必须按照这种顺序按部就班的“开始”(仅仅指的是开始,而非执行或者结束,因为这些阶段通常都是互相交叉的混合进行,通常会在一个阶段执行的过程中调用或者激活另一个阶段),而解析阶段则不一定(它在某些情况下可以在初始化阶段之后再开始,这是为了支持java语言的运行时绑定) 在以下几种情况下

非阻塞算法

和自甴很熟 提交于 2019-12-01 20:37:44
原文地址 作者: Jakob Jenkov 译者:张坤 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法。在绝大多数项目中,在算法中如果一个线程的挂起没有导致其它的线程挂起,我们就说这个算法是非阻塞的。 为了更好的理解阻塞算法和非阻塞算法之间的区别,我会先讲解阻塞算法然后再讲解非阻塞算法。 阻塞并发算法 一个阻塞并发算法一般分下面两步: 执行线程请求的操作 阻塞线程直到可以安全地执行操作 很多算法和并发数据结构都是阻塞的。例如, java.util.concurrent.BlockingQueue 的不同实现都是阻塞数据结构。如果一个线程要往一个阻塞队列中插入一个元素,队列中没有足够的空间,执行插入操作的线程就会阻塞直到队列中有了可以存放插入元素的空间。 下图演示了一个阻塞算法保证一个共享数据结构的行为: 非阻塞并发算法 一个非阻塞并发算法一般包含下面两步: 执行线程请求的操作 通知请求线程操作不能被执行 Java也包含几个非阻塞数据结构。 AtomicBoolean , AtomicInteger , AtomicLong , AtomicReference 都是非阻塞数据结构的例子。 下图演示了一个非阻塞算法保证一个共享数据结构的行为: 非阻塞算法 vs 阻塞算法 阻塞算法和非阻塞算法的主要不同在于上面两部分描述的它们的行为的第二步。换句话说

[Java] Object类中方法解析

隐身守侯 提交于 2019-12-01 19:29:11
一 概述   Object是java所有类的基类,是整个类继承结构的顶端,也是最抽象的一个类。   Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。所有的类都直接或者间接的继承自Object类。该类的设计也符合面向对象中"万事万物皆对象"的思想。   构造方法   public Object()   任何一个类都会调用这个方法,访问子类构造方法的首先会先访问父类无参的构造方法。 二 Object方法详解   Object中含有:registerNatives()、getClass()、hashCode()、equals()、clone()、toString()、notify()、notifyAll()、wait(long)、wait(long,int)、wait()、finalize()共十二个方法。   这个顺序是按照Object类中定义方法的顺序列举的,下面也会按照这个顺序依次进行讲解。 1 registerNatives()方法   private static native void registerNatives();   static {     registerNatives();   }   从名字上理解,这个方法是注册native方法(本地方法,由JVM实现,底层是C/C++实现的)向谁注册呢

给协程加上同步互斥机制

纵然是瞬间 提交于 2019-12-01 18:44:52
前面一篇文章介绍了Linux内的同步互斥的概念、内核态和用户态Linux提供的同步/互斥接口。这里本文介绍下如何给协程加上同步、互斥机制。 简单说下协程coroutine: 参考文章 操作系统的课本中对进程、线程的定义:进程是最小的资源分配单位,线程是最小的调度单位。 随着互联网的飞速发展,互联网后台Server服务通常要面临高请求、高并发的挑战,一些业务Server通常要面临很高的网络IO请求。这也就是C10K问题。 现在对C10K问题的解决方案已经很成熟了,主要是 非阻塞IO+IO复用(epoll,select等)+网络事件驱动,另外再配合多进程/多线程。 对这种非阻塞IO+IO复用+网络事件驱动的解决方案,我们通常称为异步模式,与之想对应的是同步模式。 举个简单的例子: 对于服务srvA, 对于每个前端请求的逻辑如下: 收到前端Req,访问SrvB拉取数据,然后访问SrvC拉取数据,回包Rsp给前端 对于同步模式的解决方案: 对每个前端Req都要有一个线程或者进程来处理,直到回包给前端,逻辑中的网络访过程通常用阻塞模式;无论是用线程池/进程池或者每个请求产生一个进程或者线程来处理,当前端请求量大时,系统中存在大量进程/线程时,线程的调度、占用的内核资源都是比较严重的问题。 对于异步模式的解决方案: 利用IO复用+非阻塞IO,把会导致阻塞的操作转化为一个异步操作

day30

元气小坏坏 提交于 2019-12-01 15:34:26
一、网络基础  学习网络编程,我们必须了解一些基础的网络知识  1. 我的电脑有网卡,网卡里有mac地址  2. 我到某个地方插上网线,路由器或交换机中的DHCP服务为我自动分配IP地址。       IP: 192.168.13.84        IPv4          00000000.00000000.00000000.00000000          0~255 0~255 0~255 0~255        IPV6          00000000.00000000.00000000.00000000.00000000.00000000      子网掩码:255.255.255.0 (子网掩码&ip=网段)      网关IP:192.168.13.1      局域网内、城域网、广域网:        广播        单播        广播风暴        arp协议  3、DNS    网络连接:      - 域名解析          www.baidu.com 220.181.57.216      - 连接   sk = socket.socket()   sk.connect(('47.95.64.113',80))   ...    问题来了,域名和IP的对应关系在哪里? (1)先找本地:          Win本地电脑:    

Java内存区域和内存模型

拈花ヽ惹草 提交于 2019-12-01 15:31:25
Java内存区域 Java虚拟机在运行时会将它所管理的内存划分为若干个不同的数据区域。有的区域随着虚拟机的启动而存在,有的则依赖用户的线程的启动和结束而建立和销毁。下面先看一网上的图,将的蛮好。 按照上面的划分,一共可以分为两类,7个组成部分。一类是所有线程共享的数据区,他们随着虚拟机的启动而启动。一类是依赖线程的存在而存在。 1、程序计数器 程序计数器是一块较小的内存空间,它可以看作 当前线程所执行的字节码的行号指示器 。通俗的将就是指示程序运行到哪了。 Java虚拟机的多线程就是通过线程的轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(或者一个内核)都只会执行一条线程中的指令。为了线程切换后内回到正确执行的位置,每条线程都需要一个独立的程序计数器, 各线程之间的程序计数器私有 ,互不影响。 2、虚拟机栈 与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型: 每个方法在执行的同时都会创建一个栈帧用于存储局部变量、操作数栈、动态链接、方法出口等信息 。有时候也把虚拟机栈笼统的划分为“栈”。 这也就是说,当虚拟机调用一个java方法时,该方法会被压入线程的虚拟机栈的栈帧。但是,栈帧的压入和弹出都是需要消耗时间和内存的,影响性能。从这我们也可以看出,并不是将方法分的越细越好。 3、本地方法栈

java多线程并发面试题

我怕爱的太早我们不能终老 提交于 2019-12-01 15:29:18
1、多线程有什么用? (1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 (2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。 (3)便于建模 这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D

Java内存管理:Java内存区域 JVM运行时数据区

情到浓时终转凉″ 提交于 2019-12-01 15:28:41
Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程、Class文件结构、以及JVM字节码指令。 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出给出一些HotSpot虚拟机实现的不同点和调整参数。 1、Java内存区域概述 1-2、C/C++与Java程序开发的内存管理 在内存管理领域,C/C++程序开发与Java程序开发有着完全不同的理念: 1、C/C++程序开发 自己管理内存是一项基础的工作; 自已分配内存,但也得自己来及时回收; 比较自由,但多了些工作量,且容易出现内存泄露和内存溢出等问题; 2、Java程序开发 JVM管理内存,不需要自己手动分配内存和释放内存; 不容易出现内存泄露和内存溢出; 一旦出现问题不容易排查,所以得了解JVM是怎么使用内存; 1-2、Java内存区域与JVM运行时数据区 如上图, Java虚拟机规范定义了字节码执行期间使用的各种 运行时数据区 ,即JVM在执行Java程序的过程中,会把它管理的内存划分为若干个不同的数据区域,包括: 程序计数器、java虚拟机栈、本地方法栈、java堆、方法区、运行时常量池; 从线程共享角度来说,可以分为两类: 1、所有线程共享的数据区 方法区、运行时常量池、java堆;