java文件和xml文件_用Java分割大型XML文件

java文件和xml文件

上周,我被要求用Java编写一些东西,该东西能够将一个30GB的XML文件拆分为可配置文件大小的较小部分。 文件的使用者将是一个中间件应用程序,该应用程序在XML的大尺寸方面存在问题。 在幕后,它使用某种DOM解析技术,使它在一段时间后耗尽内存。 由于它是基于供应商的中间件,因此我们无法自行纠正。 最好的选择是创建一些预处理工具,该工具会先将大文件分成多个较小的块,然后再由中间件处理。

XML文件带有一个相应的W3C模式,该模式由强制性头部分和紧随其后嵌套有多个0 .. *数据元素的内容元素组成。 对于演示代码,我以简化形式重新创建了架构:

图式 模式(1) 标头的大小可以忽略。 单个数据元素的重复也非常小,可以说少于50kB。 由于数据元素重复的次数,XML太大了。 要求是:

  • 分割后的XML的每一部分都应是语法上有效的XML,并且每一部分还应针对原始模式进行验证
  • 该工具应根据架构验证XML,并报告所有验证错误。 验证不得阻塞,且非验证元素或属性不得在输出中跳过
  • 对于标头,决定将其复制到每个新的输出文件中,而不是将其复制到每个新的输出文件中,并为每个新的输出文件重新生成标头,并提供一些处理信息和一些默认设置

因此,使用诸如Unix Split之类的二进制拆分工具是不可能的。 在固定数量的字节之后,这将拆分,从而确保XML确实损坏。 我不太确定,但是Split等工具也不了解编码。 因此,在字节“ x”之后进行拆分不仅会导致在XML元素的中间进行拆分(例如),而且甚至会在字符编码序列的中间进行拆分(例如,在使用经过UTF8编码的Unicode时)。 显然,我们需要更智能的东西。

XSLT作为核心技术也是行不通的。 乍一看,您可能会很想:使用XSLT2.0,可以从单个输入文件创建多个输出文件。 甚至可以在转换时验证输入文件。 但是,细节始终像魔鬼一样。 否则,在Java中进行简单的操作(例如将验证错误写入单独的文件或检查当前输出文件的大小)可能需要自定义Java代码。 对于Xalan和Saxon来说,当然可以有这样的扩展,但是Xalan不是XSLT2.0实现,因此只剩下Saxon。 最后但并非最不重要的一点是,XSLT1.0 / 2.0是非流式的,这意味着它们会将整个源文档读入内存,因此这显然将XSLT排除在了可能性之外。

剩下的唯一选择就是Java XML解析。 在这种情况下,当然理想的选择是StAX。 我不在这里进行SAX与StAX的比较,事实是StAX能够针对架构的身份进行验证(至少某些解析器可以)并且还可以编写XML。 此外,与SAX相比,API的使用要容易得多,因为基于pull的API提供了更多的迭代文档控制,并且比SAX的推送方式更令人愉快。 好的,我们需要什么:

  • 能够验证XML的StAX实现
    • 默认情况下,Oracle的JDK附带SJSXP作为StAX实现,但是此验证无效。
  • 最好具有某种对象/ XML映射技术,用于(重新)创建标头,而不是手动摆弄元素并必须查找正确的数据类型/格式
    • 显然是JAXB。

该代码有点大,无法在此处完整显示。 源文件,XSD和测试XML都可以访问
了这里 GitHub上。 它具有Maven pom文件,因此您应该能够在选择的IDE中将其导入。 JAXB绑定编译器将自动编译模式,并将生成的源放在类路径上。

public void startSplitting() throws Exception {XMLStreamReader2 xmlStreamReader = ((XMLInputFactory2) XMLInputFactory.newInstance()).createXMLStreamReader(BigXmlTest.class.getResource("/BigXmlTest.xml"));PrintWriter validationResults = enableValidationHandling(xmlStreamReader);int fileNumber = 0;int dataRepetitions = 0;XMLStreamWriter xmlStreamWriter = openOutputFileAndWriteHeader(++fileNumber); // Prepare first file

第一行创建了StAX流读取器,这意味着我们正在使用游标API。 迭代器API使用XMLEventReader类。 类名中还有一个奇怪的“ 2”,它表示Woodstox的StAX 2功能,其中之一可能是对验证的支持。 从
在这里 :

StAX2 is an experimental API that is intended to extend basic StAX specifications 
in a way that allows implementations to experiment with features before they 
end up in the actual StAX specification (if they do). As such, it is intended 
to be freely implementable by all StAX implementations same way as StAX, but 
without going through a formal JCP process. Currently Woodstox is the only 
known implementation.

可以在“ enableValidationHandling”中看到
源文件(如果需要)。 我将重点介绍重要的部分。 首先,加载XML模式:

XMLValidationSchema xmlValidationSchema = xmlValidationSchemaFactory.createSchema(BigXmlTest.class.getResource("/BigXmlTest.xsd"));

用于将可能的验证结果写入输出文件的回调;

public void reportProblem(XMLValidationProblem validationError) throws XMLValidationException {validationResults.write(validationError.getMessage()+ "Location:"+ ToStringBuilder.reflectionToString(validationError.getLocation(),ToStringStyle.SHORT_PREFIX_STYLE) + "\r\n");}

“ openOutputFileAndWriteHeader”将创建一个XMLStreamWriter(它又是游标API的一部分,迭代器API具有XMLEventWriter),我们可以将其输出或原始XML文件的一部分。 它还将使用JAXB创建我们的标头,并将其写入输出。 默认情况下,使用Schema编译器(xjc)生成JAXB对象。

private XMLStreamWriter openOutputFileAndWriteHeader(int fileNumber) throws Exception {XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);XMLStreamWriter writer = xmlOutputFactory.createXMLStreamWriter(new FileOutputStream(new File(System.getProperty("java.io.tmpdir"), "BigXmlTest." + fileNumber + ".xml")));writer.setDefaultNamespace(DOCUMENT_NS);writer.writeStartDocument();writer.writeStartElement(DOCUMENT_NS, BIGXMLTEST_ROOT_ELEMENT);writer.writeDefaultNamespace(DOCUMENT_NS);HeaderType header = objectFactory.createHeaderType();header.setSomeHeaderElement("Something something darkside");marshaller.marshal(new JAXBElement<HeaderType>(new QName(DOCUMENT_NS, HEADER_ELEMENT, ""), HeaderType.class,HeaderType.class, header), writer);writer.writeStartElement(CONTENT_ELEMENT);return writer;}

在第3行,我们启用“修复名称空间”。 规格说明如下:

javax.xml.stream.isRepairingNamespaces:
Function: Creates default prefixes and associates them with Namespace URIs.
Type: Boolean
Default Value: False
Required: Yes

我从中了解到,处理默认名称空间是必需的。 事实是,如果未启用,则不会以任何方式编写默认名称空间。 在第6行,我们设置默认名称空间。 设置它实际上不会将其写入流。 因此,需要writeDefaultNamespace(第9行),但这只能在写入start元素之后才能完成。 因此,您必须在编写任何元素之前定义默认名称空间,但是您需要在编写第一个元素之后编写默认名称空间。 理由是StAX需要知道它是否必须为要写yes或no的根元素生成前缀。

在第8行,我们编写了root元素。 指示此元素所属的名称空间很重要。 如果不指定前缀,则会为您生成一个前缀,或者,在本例中,将不会生成任何前缀,因为StAX知道我们已经设置了默认名称空间。 如果您要删除第6行的默认名称空间的指示,则将为根元素加上前缀(带有随机前缀),例如:<wstxns1:BigXmlTest xmlns:wstxns1 =“ http:// www…接下来,我们编写默认的名称空间,它将被写入先前开始的元素(顺便说一句,为了对此顺序有更深入的了解,请参阅这篇不错的文章 )在第11-14行中,我们使用JAXB生成的模型创建标头,然后让我们的JAXB编组器直接将其写到StAX输出流。

重要提示: JAXB编组器以片段模式初始化,否则它将开始添加XML声明,这对于独立文档是必需的,当然,在现有文档的中间是不允许的:

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

附带说明一下:在此示例中,JAXB集成并不是真正有用的,它会增加复杂性并占用更多代码行,然后仅使用XMLStreamWriter添加元素即可。 但是,如果您有一个更复杂的结构需要创建并合并到文档中,则具有自动对象映射非常方便。

因此,我们有启用验证的阅读器。 从我们开始遍历源文档的那一刻起,它将同时验证和解析。 然后,我们的writer已经编写了一个初始化的文档和标头,并准备接受更多数据。 最后,我们必须遍历源代码并将每个部分写入输出文件。 如果输出文件变大,我们将换一个新文件:

while (xmlStreamReader.hasNext()) {xmlStreamReader.next();if (xmlStreamReader.getEventType() == XMLEvent.START_ELEMENT&& xmlStreamReader.getLocalName().equals(DATA_ELEMENT)) {if (dataRepetitions != 0 && dataRepetitions % 2 == 0) { // %2 = just for testing: replace this by for example checking the actual size of the current output filexmlStreamWriter.close(); // Also closes any open Element(s) and the documentxmlStreamWriter = openOutputFileAndWriteHeader(++fileNumber); // Continue with next filedataRepetitions = 0;}// Transform the input stream at current position to the output streamtransformer.transform(new StAXSource(xmlStreamReader), new StAXResult(new FragmentXMLStreamWriterWrapper(new AvoidDefaultNsPrefixStreamWriterWrapper(xmlStreamWriter, DOCUMENT_NS))));dataRepetitions++;}
}

重要的一点是,我们不断迭代源文档,并检查是否存在Data元素的开头。 如果是这样,我们将相应的元素及其同级元素流式传输到输出。 在我们的简单示例中,我们没有兄弟姐妹,只有文本值。 但是,如果结构更复杂,则所有基础节点将自动复制到输出中。 每隔两个数据元素,我们将循环输出文件。 关闭编写器,并初始化一个新的编写器(当然可以通过检查文件大小而不是%2代替此检查)。 如果关闭了编写器,它将自动处理关闭打开的元素并最终关闭文档本身,而无需您自己执行。 作为将节点从输入流传输到输出的机制,需要注意以下几点:

  • 由于验证,我们不得不使用游标API,因此必须使用XSLT将节点及其兄弟节点传输到输出。 XSLT具有一些默认模板,如果您未专门指定XSL,则将调用这些模板。 在这种情况下,它将输入转换为给定的输出。
  • 需要一个自定义的FragmentXMLStreamWriterWrapper ,我在JavaDoc中对此进行了记录。 再次将这个包装器包装在PreventDefaultNsPrefixStreamWriterWrapper中 。 最后一个原因是默认的XSLT模板无法识别源文档中的默认名称空间。 一分钟内可以找到更多信息(或搜索避免使用DefaultDefaultNsPrefixStreamWriterWrapper)。
  • 您使用的转换器必须是Oracle JDK的内部版本。 在初始化转换器的地方,我们直接引用内部TransformerFactory的实例: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl然后创建正确的转换器: Transformer = new TransformerFactoryImpl()。newTransformer(); 通常,您将使用TransformerFactory.newInstance()并使用classpath上可用的转换器。 但是,解析器和转换器可以通过提供META-INF /服务来自行安装。 如果另一个转换器(例如默认的Xalan,而不是重新打包的JDK版本)将在类路径上,则转换将失败。 原因是显然只有JDK内部版本才可以从StAXSource转换为StAXResult
  • 转换器实际上将让我们的XMLStreamReader在迭代过程中继续。 因此,在处理完一个Data元素之后,理论上阅读器的光标将在下一个Data元素就绪。 从理论上讲,如果格式化您的XML,则下一个事件类型可能是空格。 因此,在下一个Data元素实际准备就绪之前,它仍可能需要在while循环中的xmlStreamReader.next()上进行一些迭代。

结果是我们有3个输出文件,每个输出文件都符合原始架构,每个文件都有2个数据元素:
档案
文件 要将大约30GB的XML(我在说我的原始工作分配XML具有更复杂的结构,而不是此处使用的演示XSD)拆分为大约500MB的部分,并进行了大约25分钟的验证。 为了测试内存使用率,我特意将Xmx设置为32MB。 从图中可以看出,内存消耗非常低,并且没有GV开销: bigxmltest-vm 生活是美好的,但并非完全如此。 在那儿,我发现有些尴尬的事情需要谨慎对待。

在我的实际场景中,输入XML没有与之关联的名称空间,我很确定它永远不会。 这就是我坚持使用此解决方案的原因。 在演示中,这里只有一个名称空间,并且已经开始使设置更加脆弱。 问题不在于StAX:使用StAX处理名称空间非常简单。 您可以决定具有一个与该模式的目标名称空间相对应的默认名称空间(假设您的模式为elementFormDefault = qualified),并可以为该模式中导入的其他名称空间声明一些带前缀的名称空间。 当XSLT开始干扰输出流时,问题就开始出现(您可能已经注意到了)。 显然,它不会检查已经定义了哪些名称空间或发生其他事情。

结果是,它们通过使用其他前缀重新定义现有名称空间或重置默认名称空间和其他不需要的内容,使文档严重混乱。 如果您需要比默认模板更多的名称空间操作,则可能需要XSL。 如果输入文档使用默认名称空间,则XSLT也会触发异常。 它将尝试注册名称为“ xmlns”的前缀。 不允许这样做,因为xmlns保留用于指示它不能用作前缀的默认名称空间。 我为此测试应用的解决方案是忽略任何前缀“ xmlns”,并忽略与xmlns前缀组合的目标名称空间的添加(这就是为什么我们要避免使用DefaultDefaultNsPrefixStreamWriterWrapper)。 前缀和名称空间都需要在PreventDefaultNsPrefixStreamWriterWrapper中进行匹配,因为如果您要输入的文档没有默认名称空间,而是带有前缀(例如<bigxml:BigXmlTest xmlns:bigxml =“ http://…。”> <bigxml:Header …。),那么您就不能忽略添加名称空间(该组合将成为带有“ bigxml”前缀的目标名称空间),因为这只会产生数据元素的前缀而没有名称空间绑定,例如:

<?xml version='1.0' encoding='UTF-8'?>
<BigXmlTest xmlns="http://www.error.be/bigxmltest"><Header><SomeHeaderElement>Something something darkside</SomeHeaderElement></Header><Content><bigxml:Data>Data1</bigxml:Data><bigxml:Data>Data2</bigxml:Data></Content>
</BigXmlTest>

请记住,XML的生产者可以自由选择(还是在elementFormDefault =合格的情况下)选择使用defaultnamespace还是为每个元素添加前缀。 该代码应该透明地能够处理这两种情况。 为方便起见,避免使用DefaultDefaultNsPrefixStreamWriterWrapper代码:

public class AvoidDefaultNsPrefixStreamWriterWrapper extends XMLStreamWriterAdapter {
...@Overridepublic void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {if (defaultNs.equals(namespaceURI) && "xmlns".equals(prefix)) {return;}super.writeNamespace(prefix, namespaceURI);}@Overridepublic void setPrefix(String prefix, String uri) throws XMLStreamException {if (prefix.equals("xmlns")) {return;}super.setPrefix(prefix, uri);}

最后,我还写了一个版本(点击
此处完全相同),但这次使用StAX迭代器API。 您会注意到,不再需要繁琐的XSLT来流传输到输出。 只需将每个感兴趣的事件添加到输出中即可。 通过首先使用游标API验证输入,然后使用Iterator API解析输入,可以解决缺少验证的问题。 这将花费更长的时间,但是在大多数情况下仍然可以接受。 最重要的部分:

while (xmlEventReader.hasNext()) {XMLEvent event = xmlEventReader.nextEvent();if (event.isStartElement() && event.asStartElement().getName().getLocalPart().equals(CONTENT_ELEMENT)) {event = xmlEventReader.nextEvent();while (!(event.isEndElement() && event.asEndElement().getName().getLocalPart().equals(CONTENT_ELEMENT))) {if (dataRepetitions != 0 && event.isStartElement()&& event.asStartElement().getName().getLocalPart().equals(DATA_ELEMENT)&& dataRepetitions % 2 == 0) { // %2 = just for testing: replace this by for example checking the actual size of the current// output filexmlEventWriter.close(); // Also closes any open Element(s) and the documentxmlEventWriter = openOutputFileAndWriteHeader(++fileNumber); // Continue with next filedataRepetitions = 0;}// Write the current event to outputxmlEventWriter.add(event);event = xmlEventReader.nextEvent();if (event.isEndElement() && event.asEndElement().getName().getLocalPart().equals(DATA_ELEMENT)) {dataRepetitions++;}}}}

在第2行,您将看到返回XMLEvent,其中包含有关当前节点的所有信息。 在第4行上,您看到使用此表单检查元素类型更容易(可以使用对象模型来代替与常量的比较)。 在第19行,要将元素从输入复制到输出,我们只需将Event添加到XMLEventWriter。

参考:来自Koen Serneels –技术博客博客的JCG合作伙伴 Koen Serneels 分离Java中的大型XML文件 。

翻译自: https://www.javacodegeeks.com/2013/08/splitting-large-xml-files-in-java.html

java文件和xml文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle java 并发_【转】JAVA并发教程(ORACLE官网资料)

本文是Oracle官方的Java并发相关的教程&#xff0c;感谢并发编程网的翻译和投递。计算机的使用者一直以为他们的计算机可以同时做很多事情。他们认为当其他的应用程序在下载文件&#xff0c;管理打印队列或者缓冲音频的时候他们可以继续在文字处理程序上工作。甚至对于单个应用…

部署Spring Boot Angular App(Maven和Tomcat)的4种方法

在上一篇有关Spring Boot angular 5的文章中 &#xff0c;我们使用Spring Boot angular 5实现了一个完整的堆栈端到端Web应用程序。在本文中&#xff0c;我们将讨论在tomcat上部署Spring Boot和Angle App的不同方法。 我们将创建一个具有后端&#xff08;服务器&#xff09;和前…

计算机二级web题目(8.3)--简单应用题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web3目录中&#xff0c;存有3.htm文件&#xff0c;该文件不完…

计算机二级web题目(8.4)--综合应用题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web5目录中&#xff0c;存有5.htm文件&#xff0c;该文件不完…

(3.5)HarmonyOS鸿蒙上下左右方向滑动

需要获取按下时候的坐标和松开时候的坐标&#xff0c;并将两者进行比较。 ①MainAbilitySlice.java文件 可以根据使用情况做修改代码中判断处的限制偏差范围。 package com.example.yeman.slice;import com.example.yeman.ResourceTable; import ohos.aafwk.ability.Ability…

sql 注射_基本注射/资格赛,范围

sql 注射这是上周解决的DI / CDI基础知识的延续-在本文中&#xff0c;我将讨论基础注入&#xff0c;限定词和范围。 在上一个主题中&#xff0c;我们提供了有关DI / CDI概念的大量信息&#xff0c;我们还讨论了如何使用注释加载这些bean或类-这构成了对象的组成并创建了关于如…

计算机二级web题目(9.1)--综合选择题3

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1下列叙述中正确的是(D)。 A、栈是"先进先出"的线性表 B、队列是"…

java小程序 2048_微信小程序之游戏2048

主要用来锻炼逻辑思维能力image.png可以选模式image.png这里面主要解决的问题是&#xff1a;1.判断滑动方向//在滑动块级绑定滑动开始和滑动结束的方法很原始的方法&#xff0c;startFn时保存开始的(x,y),endFn时保存结束的(x1,y2),根据这四个参数 判断方向&#xff0c;算法在方…

Java面向对象(8)--继承性

多个类中存在相同属性和行为时&#xff0c;可以将这些内容抽取到单独一个类中&#xff0c;那么多个类无需再定义这些相同的属性和行为&#xff0c;只要继承那个类即可。 这里的多个类称为子类(派生类)&#xff0c;单独的这个类称为父类(基类或超类)。 语法格式&#xff1a;cla…

aimesh node重启_华硕 RT-AC86U 和 网件 R7000 组 AiMesh 成功

家里之前买了一个 R7000 主路由器&#xff0c;后来我嫌我房间里的信号有点烂( 5G 信号只能 2 格&#xff0c;网速比 2.4G 还慢)&#xff0c;所以就入手了一个华硕 RT-AC86U 作为主路由器&#xff0c;R7000 则作为 AP。在买的时候就想组 AiMesh&#xff0c;但是因为种种事情耽搁…

maven ant_如何在Maven中运行Ant目标?

maven antmaven-antrun-plugin允许我们在各种maven构建阶段中运行ant目标。 我将专门为具有开发环境的开发人员解释maven-antrun-plugin的非常实际的用法。 通常&#xff0c;使用maven build&#xff0c;您会将项目捆绑到war文件或ear文件中。 您可以使用maven-antrun-plugin…

java中打开文件显示_在默认文件资源管理器中打开文件,并使用JavaFX或普通Java突出显示它...

我想做标题所说的.部分解决方案例如,在Windows中,您可以使用以下代码在默认资源管理器中打开文件并突出显示它.(虽然它需要修改包含空格的文件)&#xff1a;/*** Opens the file with the System default file explorer.** param path the path*/public static void openFileLo…

win10下vscode配置c语言环境

1、C编译器下载 C编译器&#xff08;MinGW-W64 GCC&#xff09;的下载&#xff1a;点击官方下载 或者点击网盘下载提取码为karj 下载完成后解压&#xff0c;将解压后的文件夹放到合适的位置&#xff0c;点开其bin子文件夹&#xff0c;复制路径。 2、win10下环境变量配置 ①…

Java面向对象(11)--多态性

父类 变量名 new 子类&#xff08;&#xff09;&#xff1b;对象的多态性&#xff1a;父类的引用指向子类的对象 Java引用变量有两个类型&#xff1a;编译时类型和运行时类型。编译时类型由声明 该变量时使用的类型决定&#xff0c;运行时类型由实际赋给该变量的对象决定。简…

Java面向对象(12)--对象类型转换 (Casting )

基本数据类型的Casting&#xff1a; ①自动类型转换&#xff1a;小的数据类型可以自动转换成大的数据类型 如long g20; double d12.0f ②强制类型转换&#xff1a;可以把大的数据类型强制转换(casting)成小的数据类型 如 float f(float)12.0; int a(int)1200L Java对象的强制…

知识蒸馏 循环蒸馏_Java垃圾收集蒸馏

知识蒸馏 循环蒸馏串行&#xff0c;并行&#xff0c;并发&#xff0c;CMS&#xff0c;G1&#xff0c;Young Gen&#xff0c;New Gen&#xff0c;Old Gen&#xff0c;Perm Gen&#xff0c;Eden&#xff0c;Tenured&#xff0c;Survivor Spaces&#xff0c;Safepoints和数百个JVM…

Javascript中的AES加密和Java中的解密

AES代表高级加密系统&#xff0c;它是一种对称加密算法&#xff0c;很多时候我们需要在客户端加密一些纯文本&#xff08;例如密码&#xff09;并将其发送到服务器&#xff0c;然后由服务器解密以进行进一步处理.AES加密和解密更加容易在相同的平台&#xff08;例如Android客户…

Java面向对象(14)--包装类的使用

针对八种基本数据类型定义相应的引用类型—包装类&#xff08;封装类&#xff09;&#xff0c;有了类的特点&#xff0c;就可以调用类中的方法。 基本数据类型 <——> 包装类&#xff0c;String——>包装类 ①装 int num 9; Integer int1 new Integer(num); Syste…

资源泄漏如何处理_处理缓慢的资源泄漏

资源泄漏如何处理使用Java监视器查找资源泄漏 查找缓慢的资源泄漏是使应用程序服务器长时间保持正常运行的关键。 在这里&#xff0c;我解释了如何使用Java监视器来发现缓慢的资源泄漏&#xff0c;以及如何验证它们是否是实际泄漏&#xff0c;而不仅仅是额外的预分配到某些HTTP…

mac php 超时,PHP---Mac上开启php错误提示

发现在使用mac 上 PHP开发项目的时候&#xff0c;程序代码错误的时候没有错误提示&#xff0c;只是提示白板。研究和查找资料才调整了一下; 步骤如下&#xff1a;1.找到php.ini文件如图所示&#xff1a;1)找到 display_errors Off &#xff0c;把Off 改为 On . 最后为 display…