小编Sco*_*ott的帖子

有没有办法在Java中强制使用弱的和/或软引用的对象?

这是我的用例.我们正在尝试缩小应用程序中潜在的内存泄漏,我们正在使用内存分析工具对堆进行快照,以便我们可以查找对象实例和引用.(如果它有帮助,我们正在使用YourKit.)

该应用程序广泛使用动态和CGLIB代理,最终在WeakHashMaps中存储大量类和类加载器的引用.

在我们的测试用例运行之后,我们期望对对象X及其类加载器的所有硬引用都消失了,但是由于测试用例中涉及很多代理,我们还有许多弱/软引用.(我只能找到WeakHashMap引用,但是YourKit将弱引用和软引用都包含在摘要中的一个行项中,所以我不能确定我在某处没有错过软引用.)

即使在从JVM请求完整GC之后也是如此.(在服务器模式下使用sun 1.6.0_23 JDK.)

看起来好像JVM承认有这些对象只弱/软引用,但我不能强迫它GC这些东西是100%肯定.(所以,我想要的是,它完全从堆中消失,其permgen的类加载器使用也会消失.)

任何人都知道配置和/或强制JVM处理仅软/弱引用的对象的方法吗?

java garbage-collection reference weak-references soft-references

12
推荐指数
1
解决办法
2274
查看次数

为什么我的 GCP 函数记录的错误应该是信息或调试?

我有一个与谷歌存储和谷歌日志记录集成的 python 3.7 谷歌云函数,因此我使用该函数部署了一个密钥文件,并使用 GOOGLE_APPLICATION_CREDENTIALS 环境变量引用它。一切都工作正常,因为我的函数执行了它应该做的事情并返回正确的输出等,唯一需要注意的是它正在将错误级别的内容记录到看起来应该是 INFO 或更低的级别。或者...也许我错过了一些东西,但我不想在这里错过一些东西。

底线:我想要干净的日志,以便错误/警告有意义,并且我不必处理噪音。

这是我的日志输出的示例: 在此输入图像描述

您会注意到,我自己的日志记录显示在“调试”级别,但在它之前和之后是看似无害的日志条目,被标记为“错误”。(是的,我知道我自己的日志条目出现了 2 次,一次在调试时,一次在信息处 - 这是另一个问题,但对我来说优先级较低。)

这对于谷歌云功能来说是正常现象吗?或者我可以做些什么来纠正这个问题?

更新:

以下是我在 python 代码中配置日志记录的方法:

import logging
import logging.config

import google.cloud.logging

client = google.cloud.logging.Client()
client.get_default_handler()
client.setup_logging()
logging.getLogger().setLevel(logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

现在,我注意到在本地调试(使用函数框架)中,我也将这些相同的消息输出到控制台,而没有任何日志条目元数据,因此通过谷歌客户端代码进行跟踪,我注意到客户端代码只是使用python 日志库,当它们在调试时输出这些消息时,它们以某种方式绕过了我期望在这里使用的 google 日志钩子。因此它们被输出到 stderr,当然谷歌的日志记录将其解释为错误。

这并没有回答我自己的问题,而是添加了更多上下文,希望其他人已经解决了这个问题。

更新 #2 - 一个丑陋的解决方案,需要一个更好的解决方案

在对谷歌云客户端代码进行了更多挖掘之后,我得到了答案,尽管我不喜欢它,也不喜欢我正在做的“修复”这个问题。

发生的事情是,当该函数在 GCP 中部署并运行时,Python 日志记录框架会以某种方式使用其他处理程序进行初始化。调用 client.setup_logging() 后,如果我打印出附加到根记录器的处理程序,我会看到:

root handlers=[<StreamHandler (NOTSET)>, <StreamHandler (WARNING)>, <CloudLoggingHandler (NOTSET)>]
Run Code Online (Sandbox Code Playgroud)

接下来,为了让事情变得更有趣,当调用 setup_logging() 时,有一些“排除的记录器”硬编码到客户端代码中,以将它们排除在使用 CloudLoggingHandler 之外(有一条注释指出,如果不这样做,我们就会请参阅无限递归)。因此,使用这些特定于 google 的记录器记录的任何内容都将始终转到我上面捕获的 StreamHandler 之一或两个。

AND,最后的解释:StreamHandler 使用的默认流是 stderr,谷歌的日志报告正确地(恕我直言)将其解释为“错误”。

因此,有了这个解释,我至少可以在我自己的函数类中使用以下代码来解决这个问题:

import logging
import google.cloud.logging

client = google.cloud.logging.Client()
client.setup_logging() # NOTE specifying …
Run Code Online (Sandbox Code Playgroud)

google-cloud-logging google-cloud-functions

12
推荐指数
1
解决办法
4094
查看次数

为什么将JVM花费这么长时间才能将GC作为无法访问的对象?

我一直在我们的应用程序中处理类加载器泄漏,最终达到了对CL的所有引用都消失的程度.在我的内存分析工具(使用YourKit和jmap/jhat)中,我可以强制GC有时会立即摆脱我的类加载器,但其他时候(取决于应用程序使用情况,但这是我可以得到的具体)当我强制GC,CL实例不会消失.我捕获一个内存快照并查看结果,它说该对象存在,但无法访问.

这是古怪的部分......我只是偶然发现了这一点.

我可以强制使用我想要的全部GC,但实例并没有消失.然而,在10-20分钟之后,如果我再做一次完整的GC,它确实会被收集.

(在此期间,申请大部分是不活动的(并非完全).我的"延长"咖啡休息时间是导致这一发现的事故.)

所以我对这里泄漏的担忧已经消失(希望如此),但问题现在更多是试图解释这种行为.

任何人都知道什么可能导致太阳JVM决定不收集无法访问的类加载器20分钟?

Sun JVM版本详细信息:

java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)
Run Code Online (Sandbox Code Playgroud)

java garbage-collection jvm classloader

9
推荐指数
2
解决办法
1520
查看次数

多模块m2eclipse/WTP项目可以将实用程序模块部署到WEB-INF/classes中吗?

我们目前使用MyEclipse与其内置的Maven4MyEclipse集成及其内置的J2EE服务器支持,但希望转换为常规eclipse(特别是Helios)以便能够在Windows上使用其64位安装.(MyEclipse在Windows上还不支持64位.)

到目前为止,我已经有了一个Helios eclipse的工作原型,使用m2eclipse和WTP插件将我们的大型Web应用程序部署到tomcat.部署有点处理器,但它可以工作,应用程序启动.

这里严重不同的是如何部署依赖项目.在我们的MyEclipse环境中,所有依赖项目都被部署到WEB-INF/classes文件夹中,因此在服务器运行时,对IDE中的java类的更改只会将受影响的文件复制到服务器的WEB-INF /类和热交换类到JVM和...繁荣 - 实时更改到服务器.非常适合调试.

然而,在我的helios转换中,所有依赖项目都获得JAR并放入WEB-INF/lib.这实际上看起来像我们真正的maven制造的生产图像看起来像,但开发环境因此严重不利,因为热交换功能似乎完全丢失了.在这里,如果我在依赖项目中更改java类,m2eclipse将重新打包JAR,看到部署的Web应用程序不同步,并重新发布整个应用程序.这不仅是一个问题,因为整个Web应用程序必须循环(鉴于它的大小和巨大的初始化时间,我们坦率地说它们做得不好),这也是eclipse在重新发布时的一个令人讨厌的延迟.(对于我们的应用程序,这需要大约一两分钟.)

所以我的问题是这样的:有没有办法让依赖项目内的更改热插拔到正在运行的JVM并替换已部署的文件而没有这种令人讨厌的重新发布惩罚?我假设这意味着将这些类文件部署到WEB-INF/classes,但不确定(a)是否可能或(b)作为此解决方案的一部分真正必要.

其他人在做什么来解决这个问题?它可以解决吗?

提前致谢!

eclipse maven-2 m2eclipse eclipse-wtp multi-module

6
推荐指数
1
解决办法
2324
查看次数

为什么我只能看到jmap -permstat中的"死"类加载器(引导程序除外)?

我们一直在推动我们应用程序中的permgen内存空间越来越高,我试图找出我们是否有某种类型的泄漏进入permgen区域.我们不做热取消部署/重新部署操作,但我们有很多代理,包括动态和CGLIB生成.我们还做了一些复杂的类加载器位来支持各种用例,我怀疑这些也可能是导致permgen浪费的一个原因.

所以我在运行的应用程序上运行jmap -permstat,希望能够深入了解可能填补我们permgen空间的内容.(我还运行带有实时和死对象的正常堆转储,这样我就可以追溯可能来自permstat输出的线索).

但是,在jmap permstat列出的2400个类加载器中,除引导类加载器之外的所有类都被列为"死".这没有任何意义,因为该应用程序绝对是直播和工作.

我的理解是,如果有资格进行垃圾收集,jmap会将类加载器报告为"死"但我在这里肯定是错的......

我错过了什么?"死"在这里意味着什么?除了我在这里可能存在的误解之外,谷歌搜索并没有提供很多答案.

java memory profiling permgen jmap

5
推荐指数
1
解决办法
2977
查看次数

Python Google Cloud 函数缺少日志条目

我正在第一次尝试 GCP 的云函数和 python,并希望将 python 的日志记录充分集成,以便它们能够很好地适应 GCP 的日志记录基础设施(特别是为了识别严重性级别,并且最好还包括execution_ids 和跟踪 id)。

我一直在关注https://cloud.google.com/logging/docs/setup/python来进行此设置。

我的代码:

import base64
import logging
import google.cloud.logging

client = google.cloud.logging.Client()
client.get_default_handler()
client.setup_logging()
logging.getLogger().setLevel(logging.DEBUG)

def sample_pubsub(event, context):
    pubsub_message = base64.b64decode(event['data']).decode('utf-8')
    print('BEFORE LOG')
    logging.info(f'Event received: payload data == [{pubsub_message}]')
    logging.debug('This is debug')
    logging.warn('This should be a warning')
    logging.error('This should be an error')
    print('AFTER LOG')
Run Code Online (Sandbox Code Playgroud)

当我使用函数框架在本地运行它时,它完美地工作(据我所知),像这样输出到控制台:

{"message": " * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)", "timestamp": {"seconds": 1609443581, "nanos": 119384527}, "thread": 140519851886400, "severity": "INFO"}
{"message": " * Restarting with …
Run Code Online (Sandbox Code Playgroud)

python logging google-cloud-logging google-cloud-functions

5
推荐指数
1
解决办法
2868
查看次数