java堆栈

java堆栈信息打印 对于java堆栈信息的打印,对于我们调试代码解决问题是非常有帮助的。java的异常机制会让我们很快的找到错误的位置。例如我的问题如下所示。 启动tomcat出现如下问题: 这只是堆栈中打印出问题的一小部分,还有很多的Exception,那是从哪一个Exception看起呢?而对于每个Exception打印的堆栈信息又是如何打印的? 对于Exception,会从底层到上层抛出,比如我的项目中用的是spirngMVC spring SpringJAP(在Dao 阅读详情

Java栈与堆

----对这两个概念的不明好久,终于找到一篇好文,拿来共享

1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

3. Java中的数据类型有两种。

一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义: 
复制内容到剪贴板代码: 
int a = 3; 
int b = 3; 
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。 4. String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = "abc";中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

5. 关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:

(1)先定义一个名为str的对String类的对象引用变量:String str;

(2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。

(3)将str指向对象o的地址。

值得注意的是,一般String类中字符串值都是直接存值的。但像String str = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。 
复制内容到剪贴板代码: 
String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true 
注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。 
结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。

我们再来更进一步,将以上代码改成: 
复制内容到剪贴板代码: 
String str1 = "abc"; 
String str2 = "abc"; 
str1 = "bcd"; 
System.out.println(str1 + "," + str2); //bcd, abc 
System.out.println(str1==str2); //false 
这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为"bcd"时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。

事实上,String类被设计成为不可改变(immutable)的类。如果你要改变其值,可以,但JVM在运行时根据新值悄悄创建了一个新对象,然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。

再修改原来代码: 
复制内容到剪贴板代码: 
String str1 = "abc"; 
String str2 = "abc";

str1 = "bcd";

String str3 = str1; 
System.out.println(str3); //bcd

String str4 = "bcd"; 
System.out.println(str1 == str4); //true 
str3这个对象的引用直接指向str1所指向的对象(注意,str3并没有创建新对象)。当str1改完其值后,再创建一个String的引用str4,并指向因str1修改值而创建的新的对象。可以发现,这回str4也没有创建新的对象,从而再次实现栈中数据的共享。

我们再接着看以下的代码。 
复制内容到剪贴板代码: 
String str1 = new String("abc"); 
String str2 = "abc"; 
System.out.println(str1==str2); //false 创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。

String str1 = "abc"; 
String str2 = new String("abc"); 
System.out.println(str1==str2); //false 
创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。

以上两段代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。

6. 数据类型包装类的值不可修改。不仅仅是String类的值不可修改,所有的数据类型包装类都不能更改其内部的值。

7. 结论与建议:

(1)我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,我们创建了String类的对象str。担心陷阱!对象可能并没有被创建!唯一可以肯定的是,指向String类的引用被创建了。至于这个引用到底是否指向了一个新的对象,必须根据上下文来考虑,除非你通过new()方法来显要地创建一个新的对象。因此,更为准确的说法是,我们创建了一个指向String类的对象的引用变量str,这个对象引用变量指向了某个值为"abc"的String类。清醒地认识到这一点对排除程序中难以发现的bug是很有帮助的。

(2)使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。这个思想应该是享元模式的思想,但JDK的内部在这里实现是否应用了这个模式,不得而知。

(3)当比较包装类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==。

(4)由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。


消失的Java堆栈 前言 这周的某天突然爆出线上查询卖家订单异常的报警,因为这个接口量比较大,赶紧排查马上介入看了下,找到日志后发现这个接口的实现抛了NPE,但是在日志里看不到堆栈。因为封网的时间已经很长了,应该不是发布导致的。但无论如何,要先定位到抛NPE的地方,才能知道是哪里出了问题 消失的堆栈 我们用下面的代码来做一次测试 publicclassDemoApplication{ publicstaticvoidmain(String[]args){ //SpringApplication... 阅读详情

相关推荐

RK3576开发板ROS2部署实战:从Buildroot配置到Hello World Demo

本文详细介绍了在RK3576开发板上部署ROS2的完整实战流程。从Buildroot工程配置、集成ROS2依赖,到搭建Docker交叉编译环境、处理编译难题,最终完成系统镜像打包并在板端成功运行Talker-Listener Demo。该指南旨在帮助开发者深入理解嵌入式机器人系统的构建链,实现从底层到应用的完全掌控。

mac99的博客 1154

java集合之LinkedList详解

我们上一次说到List的ArrayList,我们这次去看下LinkedList---顾名思义是链表,链表的优点就不用说了吧,增删效率比较高(具体的朋友们上网看吧),先来看下LinkedList的整体构架:  首先我们看到了LinkedList间接的实现了List接口(说明LinkedList是有list的特性的,add,remove等)、实现了Cloneable(可复制)、Serializa...

zhao_xinhu的博客 2万+

【医学图像分割网络】之Res U-Net网络PyTorch复现

【医学图像分割网络】之Res U-Net网络PyTorch复现 1.内容 U-Net网络算是医学图像分割领域的开山之作,我接触深度学习到现在大概将近大半年时间,看到了很多基于U-Net网络的变体,后续也会继续和大家一起分享学习。这次分享ResNet+U-Net的一个改进版,ResNet本身就是一个十分优秀的backbone,目前应用仍然十分广泛,我们融合进ResNet后,我们就可以使得U-Net进行迁移学习了。 1.将Resnet作为encoder替换U-Net原始结构 2.U-Net提出时间较早,当时还没

qq_39071739的博客 1万+

Java堆栈

Java堆栈 jvm为每个新创建的线程都分配一个堆栈。堆栈以帧为单位保存线程的状态。jvm对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。 某个线程正在执行的方法称为此线程的当前方法。当前方法使用的帧称为当前帧。当前方法所属的类称为当前类。当前类的常量池称为当前常量池。当线程执行一个方法时,它会跟踪当前的类和常量池。当jvm会在当前帧内执行帧内数据的操作。 当线程激活一个j

一名教育的被实验者 5537

DPARSF高级版 vs 基础版怎么选?没有T1数据也能做fMRI分析吗?

本文深度对比了DPARSF高级版与基础版在fMRI分析中的核心差异与适用场景,特别针对无T1数据的情况提供了实战解决方案。高级版依赖T1像实现高精度配准,适合需要精确解剖定位的研究;基础版则无需T1数据,适用于功能连接等相对空间要求不高的分析。文章还提供了版本选择决策树和常见问题解决方案,帮助研究者根据实际需求做出最优选择。

weixin_42526087的博客 132

STM32F103C8T6键盘DIY全攻略:从电路设计到固件烧录(附避坑指南)

本文详细介绍了基于STM32F103C8T6微控制器的DIY键盘制作全流程,涵盖硬件电路设计、按键矩阵实现、USB HID通信及固件烧录等关键步骤。特别针对常见问题提供避坑指南,帮助开发者高效完成从电路设计到功能实现的完整过程,打造个性化瀚文键盘。

soda5的博客 770

Java问题定位之Java线程堆栈分析

采用Java开发的大型应用系统越来越大,越来越复杂,很多系统集成在一起,整个系统看起来像个黑盒子。系统运行遭遇问题(系统停止响应,运行越来越慢,或者性能底下,甚至系统宕掉),如何速度命中问题的根本原因是我们接下来讲的目的。本系列文章将Java问题定位的方法体系化,提供一种以黑盒子方式进行问题定位的思路:如何使用线程堆栈进行性能瓶颈分析?如何分析内存泄漏?如何分析系统挂死? 文章思路 总

weiweicao0429的专栏 2万+

提取abaqus中节点集合的应力应变

节点是没有应力应变的,只有积分点才有,所以直接在odb文件里面用FieldOutput是整不出来的(结果是个空列表),只能用session这种让abaqus自己帮你处理。具体的代码需要根据自己操作的时候abaqus.rpy这个文件中代码的变化来更改。

蓝胖子的博客 4553

java 堆栈_java-如何打印堆栈信息

前言在做调试bug的时候, 想测试知道这些流程是怎么调用的, 就需要打印其堆栈信息 这里只是封装了一个工具函数, 看自己使用代码如下public static void printCallStack() { printCallStack(0); } public static void printCallStack(int elementMax) { printCallStack(eleme...

weixin_39722196的博客 1003

开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述

综上,大多数工作均基于CLIP预训练的图像编码器和文本编码器。GlIP为解决目标检测任务提供了先例,后续很多工作常与目前较为广泛使用的目标检测网络结构相结合,从而构建新的开放词汇目标检测器。如ViLD基于Mask R-CNN、RegionCLIP基于R-CNN、VLDet和BARON基于Faster R-CNN。更具有创新性的工作是Detic,提出了使用图像分类的数据集来对目标检测器的分类头进行训练。

yangsn0719的博客 4400

UG NX二次开发(C#)-外部模式-批量删除某些图层中的体对象和曲线对象

在 UG NX中,有时需要批量删除某文件夹下多个.prt文件中固定一些图层中的体对象和曲线对象,这时如果采用手动逐个打开模型,并选择针对的图层删除,即耗时也容易遗漏,因此采用外部模式来处理比较方便。本文介绍批量删除某些图层中的体对象和曲线对象。

GimiGimmy 3035

java堆栈(java堆栈信息怎么看)

什么是堆栈溢出的堆栈区域呢? 堆栈既可以向下增长(向内存低地址)也可以向上增长,这依赖于具体的实现 Java堆栈溢出的机制与原理是什么? Java堆栈溢出的出现,很让人痛苦的事情,很多时候都无法找到头绪。这里作者通过使用jrockit调用程序才最终发现了问题的所在。在很多情况下,Java堆栈溢出,很有可能是你...

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 539

【AVRCP】规范精讲[19]: 媒体属性全解析,让你的蓝牙设备显示完整歌曲信息

AVRCP协议中的媒体属性是蓝牙音频设备传输歌曲元数据的关键,包含标题、艺术家、专辑等32位ID标识的键值对信息。规范要求字符串属性必须使用UTF-8编码,但乱码问题频发(如中文显示异常),主因是设备未遵循编码标准或使用GBK等非规范格式。常见问题包括信息不全(仅显示标题)、封面缺失(因带宽限制或格式不支持)及更新延迟(通知机制未启用)。解决方案包括强制UTF-8编码、优化封面大小(如300x300像素JPEG)、主动请求缺失属性。Android示例代码展示了通过广播接收器解析媒体属性的方法。

byte轻骑兵的技术小窝 1万+

java打印线程堆栈_Java问题定位之Java线程堆栈分析

采用Java开发的大型应用系统越来越大,越来越复杂,很多系统集成在一起,整个系统看起来像个黑盒子。系统运行遭遇问题(系统停止响应,运行越来越慢,或者性能低下,甚至系统宕掉),如何速度命中问题的根本原因是我们接下来讲的目的。本系列文章将Java问题定位的方法体系化,提供一种以黑盒子方式进行问题定位的思路:如何使用线程堆栈进行性能瓶颈分析?如何分析内存泄漏?如何分析系统挂死?目录总述如何输出线程堆栈?...

weixin_33016287的博客 1730

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java线程堆栈信息分析

java堆栈信息分析

qq727923587的博客 4240

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java线程堆栈_深入JVM剖析Java的线程堆栈

在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因。在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术。在线程堆栈中存储的信息,通常远超出你的想象,我们可以在工作中善加利用这些信息。我的目标是分享我过去十几年来在线程分析中积累的知识和经验。这些知识和经验是在各种版本的JVM以及各厂商的JVM供应商的深入分析中获得的,在这个过程中我也总结出大量的...

weixin_32868705的博客 718

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

用java编写堆栈

相比于十年前,现今对编程的学习要简单的多,现今有很多成熟 的编程工具可用,而且有很多的辅助编程的工具可用,比如说chatgpt,它能回答我们众多的提问,我们只需要知道如何向它提问,就能完成超多的编程任务。四、上面的堆栈有其缺陷,它的内部数组的大小是固定的,当数据量较小时会浪费空间,在数据量较大时可能又不够用,毕竟程序在使用的过程中会出现何种情况是无法预知的。//存储栈的最大索引,个人的不良习惯,喜欢把数据弄的明明白白的,即使是有冗余。当然,这里我们想了解堆栈的具体实现,我们就要自己尝试编写实现堆栈。

qq_40793198的博客 944

如何看java堆栈信息

如何看Java堆栈信息 在Java开发过程中,我们常常会遇到各种各样的问题。这些问题可能是由于代码中的错误、内存泄漏或者系统性能问题引起的。了解如何查看和分析Java堆栈信息是排除故障的重要手段之一。本文将通过一个实际的例子,介绍如何查看Java堆栈信息以及如何理解它所提供的线索。 什么是Java堆栈信息 Java堆栈信息...

weixin_41848533的博客 562

java 堆栈大小设置_如何增加Java堆栈大小?

如何增加Java堆栈大小?我问这个问题是为了了解如何在JVM中增加运行时调用堆栈的大小。 我已经得到了答案,我还得到了许多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况有关。 我已经用答案摘要扩展了我的问题。最初我想增加JVM堆栈大小,以便像没有fact的程序运行。public class TT {public static long fact(int n) {retu...

weixin_32546235的博客 2927

一文读懂Java线程堆栈

详细介绍了什么是Java线程堆栈;如何获取Java线程堆栈信息;如何解读堆栈信息;如何借助堆栈信息分析常见问题

love_eat_peach的博客 2529

android 打印java堆栈,Android打印堆栈

java打印堆栈方法一:异常对象打印堆栈Exception e = new Exception("this is a log");e.printStackTrace();方法二:Log打印获取异常的堆栈并打印Log.e(“dump_test”,Log.getStackTraceString(new Throwable()));C++\C打印堆栈方法一:linux函数函数介绍头文件:java#inc...

weixin_29191761的博客 861

Java线程堆栈信息查看

Linux 下Java程序的线程堆栈查看方法: 第一步:在终端运行Java程序 第二步:通过命令 pidof java 找到已经启动的java进程的ID,选择需要查看的java程序的进程ID 第三步:使用命令 kill -3 打印出java程序的线程堆栈信息 第四步:通常情况下运行的项目可能会比较大,那么这个时候打印的堆栈信息可能会有几千到几万行,为了方便查看,我们往往需要将输出内容进行

不断成长的我 1万+

java怎么增加堆栈_如何增加Java堆栈大小?

如何增加Java堆栈大小?我问了这个问题,以了解如何增加JVM中的运行时调用堆栈大小。 我已经得到了一个答案,而且我也得到了很多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况相关。 我已经回答了问题的总结。最初我想增加JVM堆栈的大小,所以像没有StackOverflowError运行的程序。public class TT { public static long fa...

weixin_35578748的博客 1053

java创建堆栈_Java创建和读取堆栈跟踪

示例当创建异常对象时(即当您创建异常对象时new),Throwable构造函数将捕获有关在其中创建异常的上下文的信息。稍后,该信息可以以堆栈跟踪的形式输出,该堆栈跟踪可用于帮助诊断最初导致异常的问题。打印堆栈跟踪打印stacktrace只需调用该printStackTrace()方法即可。例如:try{inta=0;intb=0;intc=a/b;}catch(Arit...

weixin_30131443的博客 442

android java 堆栈_Android下打印调试堆栈方法

android java 堆栈_Android下打印调试堆栈方法

Android framework 1222

java 打印堆栈_Java 打印堆栈的方法

方法一.Exception e = new Exception("this is a log"); //相应的log标记e.printStackTrace();//延迟才可以看出效果//Thread.currentThread().sleep(1000);//System.out.println("-------------以上是异常详细信息----------------");方法二 .Stri...

weixin_30635707的博客 1910
上一篇: Office200X打开文件提示“您尝试打开的文件xxx.xls的格式与文件扩展名指定的格式不一致”的解决办法
下一篇: 从程序员到技术总监,分享10年开发经验
池哥搬砖
博客等级 码龄17年 255粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值