原文出处: codelog.me 大家知道,Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,就会在字符串常量池中创建该字符串然后再返回. 字符串常量池是一个固定大小的HashMap,桶的数量默认是1009, 从Java7u40开始,该默认值增大到60013.在Java6当中,字符串常量池是放在Perm空间的,从Java7开始,字符串常量池被移到Heap空间.下面,我们通过测试程序来窥探字符串常量池在Java6,Java7两个不同版本底下的内…
目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 设置最大堆内存 2.2 设置最小堆内存 2.3 设置新生代 2.4 设置持久代 2.5 设置线程栈 2.6 堆的内存分配 2.7 堆分配参数总结 3.垃圾收集基础 3.1 垃圾收集的作用 3.2 垃圾回收算法与思想 3.2.1 引用计数法(Reference Counting) 3.2.2 标记-…
通过反编译深入理解Java String及intern 原文传送门:http://www.cnblogs.com/paddix/p/5326863.html 一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会问应聘者相关的问题,倒不是说一定要回答的特别正确和深入,通常问这些问题的目的有两个,第一是考察对 JAVA 基础知识的了解程度,第二是考察应聘…
String是Java中最常用的类,是不可变的(Immutable), 那么String是如何实现Immutable呢,String为什么要设计成不可变呢? 前言 关于String,收集一波基础,来源标明最后,不确定是否权威, 希望有问题可以得到纠正. 0. String的内存模型 Java8以及以后的字符串新建时,直接在堆中生成对象,而字符创常量池位于Metaspace.必要的时候,会把堆中的指针存入Metaspace, 而不是复制. Metaspace位于虚拟机以外的直接内存,因此大小和外部…
JVM内存模型 Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: 1. 程序计数器 2. Java虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区. 下面对这五个区域展开深入的介绍. 1. 程序计数器 1.1. 什么是程序计数器? 程序计数器是一块较小的内存空间,可以把它看作当前线程正在执行的字节码的行号指示器.也就是说,程序计数器里面记录的是当前线程正在执行的那一条字节码指令的地址. 注:但是,如果当前线程正在执行的是一个本地方法,那么此时程…
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更快的定位到一些bug,也能进行相关的性能调优等. 二.java虚拟机的内存模型 1.java堆(java heap): java虚拟机在启动的时候会创建java堆,它是java虚拟机所管理的内存最大的一块. 其作用就是存放对象的实例,几乎所有的对象都是在这里存放. 这个区域是由所有线程共享的,它也是…
一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想法:方法中的局部变量在运行的时候,是存在JAVA栈中的,方法运行结束,局部变量也就都弹光了,理论上单线程的话是不会有问题的,我之所以不知道,是因为不清楚在JAVA内存模型中,一个线程对应一个栈,还是多个线程共享一个栈... 其实如果知道每个线程都有一个自己的JAVA栈的话,问题也就很清楚了,不会被其…
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到较为合理的内存使用,由此引发了我的一些关于内存方面的疑问: 一个类的对象占内存多少?其大小由什么决定? Java类中过长的方法会不会影响类的对象大小? 将过长的方法封装会不会影响原来的运行速度? 一个或者多个Java对象的内存模型图 第一种比较简单的情况: public class Boy{ pri…
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实例的时候,虚拟机要为对象分配内存,Java虚拟机又是如何配分内存的呢?这些都涉及到Java虚拟机的内存划分机制,今天我们就来探究一下Java虚拟机的内存模型. Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间,有的区域随…
一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会问应聘者相关的问题,倒不是说一定要回答的特别正确和深入,通常问这些问题的目的有两个,第一是考察对 JAVA 基础知识的了解程度,第二是考察应聘者对技术的态度. 我们看看以下程序会输出什么结果?如果你能正确的回答每一道题,并且清楚其原因,那本文对你就没什么太大的意义.如果回答不正确或者不是很清楚其原理…
一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会问应聘者相关的问题,倒不是说一定要回答的特别正确和深入,通常问这些问题的目的有两个,第一是考察对 JAVA 基础知识的了解程度,第二是考察应聘者对技术的态度. 我们看看以下程序会输出什么结果?如果你能正确的回答每一道题,并且清楚其原因,那本文对你就没什么太大的意义.如果回答不正确或者不是很清楚其原理…
原文链接:https://www.cnblogs.com/paddix/p/5326863.html 一.字符串问题 字符串在我们平时的编码工作中用的非常多,并且用起来非常简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题. 我们看看一下程序会输出什么结果?如果你能正确的回答每一道题,并且清楚原因,那本文对你没什么太大的意义.如果回答不正确或者不是很清楚其原理,那就仔细看看一下的分析,本文应该能帮助你清楚的理解每段程序的结果及输出该结果的深层次原…
1.概述 对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要手动释放内存,不容易出现内存泄露和内存溢出问题.一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,排查错误将会异常艰难. 2. 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.Java虚拟机hotspot所管理的内存包括以…
经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发.确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些. JVM 的重要性 首先你应该知道,运行一个 Java 应用程序,我们必须要先安装 JDK 或者 JRE .这是因为 Java 应用在编译后会变成字节码,然后通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分. 优点 JVM 不仅承担了 Java 字节码的分析(JIT compiler)和执行(Ru…
运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Register.如果翻译为程序寄存器更加合理. 因为这块内存区域很小,功能也类似于寄存器.所以还是翻译寄存器比较靠谱. 在虚拟机的概念模型中(仅仅是概念模型,虚拟机可以通过一些更高效的方式来实现),字节码解释器会通过改变程序计数器的值来选取下一条需要执行的字节码指令. 因为CPU是要轮转的,在切换回来之后,J…
Java与C++之间有一堵由内存动态分配和垃圾回收技术所围成的"高墙",墙外的人想进去,墙外的人想出来.--<深入理解Java虚拟机> 前言 <深入理解Java虚拟机>,学习JVM的经典著作,几乎学习JAVA的小伙伴人手一本.当初买了,翻看了一部分,到了字节码那边彻底读不下去了,遂弃之.最近打算看Spring源码,反射.动态代理.设计模式等基础工具的确可以让我更加容易理解源码内容.然而,看着看着才发现,这个平常我们几乎用不到的东西(除了面试),才应该是理解jav…
一.概述 我们在进行 Java 开发的时候,很少关心 Java 的内存分配等等,因为这些活都让 JVM 给我们做了.不仅自动给我们分配内存,还有自动的回收无需再占用的内存空间,以腾出内存供其他人使用.但是我们经常面临的一个问题就是内存泄漏,JVM无法完成回收工作,导致内存占用暴涨,最后可能让程序奔溃.本章主要了解下运行时数据区域分布情况以及溢出异常. 二.运行时数据区域 1.程序计数器 线程私有 当前线程所执行的字节码的行号指示器 Java 多线程是通过再一个内核中轮流执行实现的,计数器就保证了…
在Java语言了中,所有类似“ABC”的字面值,都是String类的实例:String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较.查找.截取.大小写转换等操作:Java语言为“+”连接符(字符串连接符)以及对象转换为字符串提供了特殊的支持,字符串对象可以使用“+”连接其他对象.String类的部分源码如下: public final class String implements java.io.Serializable, Comparable<String>,…
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就需要了解一些底层的知识来进行错误排查. 自动内存管理机制:介绍内存是如何划分的. 垃圾收集器与内存分配策略:分析垃圾收集算法. 虚拟机性能监控与故障处理工具 调优案例分析与实战 第三部分:虚拟机执行子系统 类文件系统:介绍Class文件结构的各个组成部分. 虚拟机类加载机制:介绍类加载过程的各个阶段…
前言 JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解JVM必要的知识点. 一.运行流程 我们都知道java一直宣传的口号是:一次编译,到处运行.那么它如何实现的呢?我们看下图: java程序经过一次编译之后,将java代码编译为字节码也就是class文件,然后在不同的操作系统上依靠不同的java虚拟机进行解释,最后再转换为不同平台的机器码,最终得到执行.这样我们是不是可以推演,如果要在m…
参考:https://www.jianshu.com/p/0d1c003d2ff5 String.intern() String.intern()是native方法,底层调用c++中的StringTable:intern方法. 当调用intern方法是,如果常量池已经存在该字符串,则返回池中字符串. 否则将此字符串添加到常量池中,并返回字符串的引用. package com.ctrip.ttd.whywhy; class Test { public static void main(String…
多任务处理在现代计算机操作系统中是一项必备的功能,让计算机同时去做几件事情,不仅是因为计算机的运算能力强大了,更重要的原因是计算机的运算速度与它的存储和通信子系统速度的差距太大,大量的时间都花费在磁盘I/O,网络通信或者数据库访问上,因此处理器在大部分时间里都处于等待其他资源的状态. 如果让计算机并发执行若干个运算任务就可以更充分地利用计算机处理器的效能,但是其中的复杂性是绝大多数的运算任务都不可能只靠处理器计算就能完成,处理器至少要与内存交互,如读取运算数据.存储运算结果等,这个I/O操作无法…
通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收实例对象,就会在对象数量达到堆最大容量时产生OutOfMemoryError异常. 想要方便快速地产生堆溢出,要使用如下java虚拟机参数:-Xms10m(最小堆内存为10MB),-Xmx10m(最大堆内存为10MB,最小堆内存和最大堆内存相同是为了避免堆动态扩展),-XX:+HeapDumpOnO…
博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 下文是博主感悟,请带着怀疑性的态度阅读! 需要了解基本变量所占内存大小,请移步:读书笔记-类结构的认识 Java存储空间有这么几块-来源于Java编程思想 寄存器:位于处理器内部,不受外层代码控制,由处理器自行分配-C/C++可以建议分配方式 堆栈:位于RAM中  引用和基本数据类型存放的区块. 指针向下生成新对象,向上释放对象(new关键字),相当于链表结构…
本文转载自: http://blog.sina.com.cn/s/blog_5203f6ce0100tiux.html 要理解 java中String的运作方式,必须明确一点:String是一个非可变类(immutable).什么是非可变类呢?简单说来,非可变类的实例是不能被修改的,每个实例中包含的信息都必须在该实例创建的时候就提供出来,并且在对象的整个生存周期内固定不变.java为什么要把String设计为非可变类呢?你可以问问 james Gosling :).但是非可变类确实有着自身的优势…
1. 引言 2. Java内存模型 3. 内存间的交互操作 1. 引言 考虑到计算机组成的内容: 原始的计算机是CPU用于计算+硬盘用于存储,由于CPU的高速发展和硬盘的缓慢发展,高速的存储需要持续供电且价格昂贵,于是引入了由高速存储组成的内存作为中间的缓冲层.形成了CPU-RAM-Main Memory的金字塔结构. 接下来,由于CPU的继续发展,内存也渐渐跟不上CPU的速度,于是引入了更小更高速的cache作为CPU和内存的缓冲.形成了我们现在熟悉的计算机组成金字塔结构. 然后,由于CPU从…
概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很多,该语言针对多种异构平台的平台独立性而使用的多线程技术支持也是具有开拓性的一面,有时候在开发Java同步和线程安全要求很严格的程序时,往往容易混淆的一个概念就是内存模型.究竟什么是内存模型?内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节,对象最终是存储在内存里面的,这点没有错,但是编译器.运行库.处理器或…
栈内存 堆内存 基础类型,对象引用(堆内存地址) 由new创建的对象和数组, 存取速度快 相对于栈内存较慢 数据大小声明周期必须确定 分配的内存由java虚拟机自动垃圾回收器管理.动态分配内存大小 共享特性 栈中如果有字符串,则直接引用 如果没有,开辟新的空间存入值 每new一次在堆内存中生成一个新的对象. 创建之后值可以改变 String类声明后则不可改变 一.== 内存地址比对 String str1 = "abc"; //str1常量池 String str2 = "a…
内部java内存模型 硬件层面的内存模型 Java内存模型和硬件内存模型的联系 共享对象的可见性 资源竞速 Java内存模型很好的说明了JVM是如何在内存里工作的,JVM可以理解为java执行的一个操作系统,作为一个操作系统就有内存模型,这就是我们常说的JAVA内存模型. 如果我们想正确的写多线程的并行程序.理解好java内存模型在多线程下的工作方式是及其重要的,这可以帮我们更好的理解底层的工作方式. java内存模型说明了不同的线程怎样以及何时可以看到其他线程写入共享变量的值,以及同步程序怎么…
共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入时,能对另一个线程可见.从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本.本地内存是JMM的一个抽象概念,并不真实存在.它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化. 从上图来看,线程A与线程B之间如要通信的话,必须要经历下面2…