小编Ogr*_*gre的帖子

Java垃圾收集器 - 定期运行不正常

我有一个不断运行的程序.通常,它似乎是垃圾收集,并保持在大约8MB的内存使用量.然而,每个周末,它都拒绝垃圾收集,除非我明确地打电话给它.但是,如果它接近最大堆大小,它仍将是垃圾收集.然而,注意到这个问题的唯一原因是因为它实际上在一个周末因内存耗尽而崩溃,即它必须达到最大堆大小,而不是运行垃圾收集器.

下图(单击以查看)是程序一天内存使用情况的图表.在图的两侧,您可以看到程序内存使用情况的正常行为,但第一个大峰似乎是周末开始的.这个特殊的图是一个奇怪的例子,因为在我对垃圾收集器进行了一次显式调用之后,它成功运行了,但随后它又回到了最大堆大小并成功地自己垃圾收集了两次.

这里发生了什么?

编辑:

好的,从评论来看,似乎我没有提供足够的信息.该程序简单地接收UDP包,其被放置在队列中(设置为具有1000个对象的最大尺寸),然后将其加工成具有存储在数据库中其数据流.平均而言,它得到每秒约80报文,但峰值150它是运行在Windows Server 2008上运行.

问题是,这个活动是相当一致的,如果有的话,在内存使用量开始它的稳步攀升的时候,活动应该就低不就高.你要知道,我上面贴的图是唯一一个我有一个向后延伸那么远,因为我不仅改变了Java可视虚拟机的包装,以保持图形数据回远到足以目睹它这个星期,所以我不知道它是否准确每周同一时间,因为我不能看着它在周末,因为它是一个专用网络上,我不是在周末工作.

这是第二天的图表: 替代文字

这几乎是内存使用情况每周的其他日子.程序永远不会重新启动,我们只会在周一早上告诉它垃圾收集因为这个问题.一周我们尝试在周五下午重新启动它,它在周末的某个时候仍然开始爬升,所以我们重启它的时间似乎与下周的内存使用没有任何关系.

它成功地垃圾收集所有这些对象的事实,当我们告诉它暗示对象是可收集的时,它只是在它达到最大堆大小时才执行它,或者我们显式调用垃圾收集器.堆转储没有告诉我们什么,因为当我们尝试执行一个时,它突然运行垃圾收集器,然后输出堆转储,这当然看起来完全正常.

所以我想我有两个问题:为什么它突然没有垃圾收集它在本周其余时间进行的方式,为什么在一个场合,当达到最大堆大小时发生的垃圾收集无法收集所有这些对象(也就是说为什么一次都会引用这么多对象,而每隔一段时间一定不会有这样的对象)?

更新:

今天早上很有趣.正如我在评论中提到的,该程序正在客户端的系统上运行.我们在客户组织中的联系人报告说,凌晨1点,该程序失败了,他今天早上上班时必须手动重启,而且服务器时间再次不正确.这是我们过去曾经遇到的一个问题,但直到现在,这个问题似乎从来没有关系过.

查看我们的程序生成的日志,我们可以推断出以下信息:

  1. 在01:00,服务器以某种方式重新启动它的时间,将其设置为00:28.
  2. 在00:45(根据新的,不正确的服务器时间),程序中的一个消息处理线程抛出了内存不足错误.
  3. 但是,另一个消息处理线程(我们收到两种类型的消息,它们的处理方式略有不同,但它们都不断进入),继续运行,并且像往常一样,内存使用量继续攀升而没有垃圾回收(从我们记录的图表中可以看出,再一次).
  4. 在00:56,日志停止,直到早上7点,我们的客户重新启动程序.但是,此时的内存使用情况图仍在稳步增长.

不幸的是,由于服务器时间的变化,这使得我们的内存使用图上的时间不可靠.但是,它似乎是尝试垃圾收集,失败,将堆空间增加到最大可用大小,并立即杀死该线程.既然最大堆空间已经增加,它很乐意在不执行主要垃圾收集的情况下使用所有堆空间.

所以现在我问这个问题:如果服务器时间突然像它一样突然改变,那会不会导致垃圾收集过程出现问题?

java garbage-collection

16
推荐指数
1
解决办法
8298
查看次数

Android launchmode ="singleTask"无法按预期工作

我有一个在后台运行的应用程序,并通过通知系统显示错误消息.此通知具有pendingIntent,可以返回应用程序的主屏幕.在这个主屏幕上,我设置了launchmode ="singleTask".正如我从Android开发指南中理解的那样,这应该意味着我的主要活动将只有一个实例.

但是,如果用户当时正在查看该活动(或应用程序中的另一个活动),然后触摸通知以清除它,它会继续并将活动的另一个副本放在堆栈上,所以如果我点击了后退按钮,它将再次返回主屏幕(从主屏幕).

为什么要这样做?

android

13
推荐指数
1
解决办法
2万
查看次数

如何在Android上使用Google URL Shortener API?

在尝试自己导入库之后,我终于设法发现我可以使用Google Plugin for Eclipse这样做.

但是,我似乎无法找到如何在Android上实际使用API​​的任何示例,至少没有可编译的,因为这些示例中所需的类似乎无法由Eclipse解析,所以我只能假设这些Google Plugin for Eclipse为URL Shortener API导入的库中不存在类.我能找到的最接近的例子就是这里,它似乎是针对谷歌应用引擎,而不是Android,并使用我似乎无法访问的类.

所以问题是,如何在Android应用程序中使用此API来获取URL的缩短版本?我希望使用API​​密钥代替OAuth.

android google-url-shortener

6
推荐指数
2
解决办法
9609
查看次数

为什么 EncryptedSharedPreferences 会抛出 InvalidProtocolBufferException?

我正在尝试初始化检索我的应用程序的 EncryptedSharedPreferences。我发现在一台设备(运行 Android 11 的三星 Galaxy A52)上,由于 InvalidProtocolBufferException 的调用,应用程序在启动时崩溃EncryptedSharedPreferences.create()。我无法在其他设备上重现此问题,包括运行 Android 12 的三星 Galaxy A52。

    private var encryptedPrefs = EncryptedSharedPreferences.create(
        "keystoreFileName",
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        this, // "this" is my main activity
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
Run Code Online (Sandbox Code Playgroud)

这是例外情况:

com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
Run Code Online (Sandbox Code Playgroud)

同一函数调用还有一个较早的异常,但记录为警告。

android.security.KeyStoreException: Signature/MAC verification failed
Run Code Online (Sandbox Code Playgroud)

可能是什么原因造成的?应该如何解决?

android kotlin

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

使用build.gradle文件将Eclipse项目导入Android Studio失败

我正在尝试使用build.gradle文件导入基于Eclipse的Android项目.我收到以下消息:"找不到Build Tools版本18.0.0".但是,根据Android SDK Manager,我安装了Android SDK Build-tools 18.0.1.

我正在64位Windows 7机器上做这一切,如果这是相关的.

我该如何解决?

更新:我实际上今天早上只更新了Build-tools 18.0.1.然后我注意到,在Android Studio中创建一个新项目时,它不允许我使用Android 4.3创建项目(4.2.2是最新的允许版本).我尝试将我的项目的目标版本删除到Android 4.2.2,并重新导出它.现在Android Studio抱怨在我尝试导入这个项目时无法找到Build-tools 18.0.1.

android android-studio build.gradle

5
推荐指数
3
解决办法
6099
查看次数

处理从 Kafka 检索到的每条记录后,提交的正确方法是什么?

我在理解如何为我使用的每条记录正确手动提交时遇到了一些麻烦。

首先,让我们看一个来自https://kafka.apache.org/090/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html的例子

while (true) {
     ConsumerRecords<String, String> records = consumer.poll(100);
     for (ConsumerRecord<String, String> record : records) {
         buffer.add(record);
     }
     if (buffer.size() >= minBatchSize) {
         insertIntoDb(buffer);
         consumer.commitSync();
         buffer.clear();
     }
 }
Run Code Online (Sandbox Code Playgroud)

此示例仅在处理了轮询中收到的所有记录后才提交。我认为这不是一个很好的方法,因为如果我们收到三个记录,而我的服务在处理第二个记录时死亡,它最终将再次消耗第一条记录,这是不正确的。

因此,还有第二个示例涵盖了在每个分区的基础上提交记录:

try {
     while(running) {
         ConsumerRecords<String, String> records = consumer.poll(Long.MAX_VALUE);
         for (TopicPartition partition : records.partitions()) {
             List<ConsumerRecord<String, String>> partitionRecords = records.records(partition);
             for (ConsumerRecord<String, String> record : partitionRecords) {
                 System.out.println(record.offset() + ": " + record.value());
             }
             long lastOffset = partitionRecords.get(partitionRecords.size() - 1).offset();
             consumer.commitSync(Collections.singletonMap(partition, new OffsetAndMetadata(lastOffset + 1)));
         }
     } …
Run Code Online (Sandbox Code Playgroud)

java kotlin apache-kafka

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

是否可以声明Range类型的变量或常量?

在Ada中,我们可以使用范围获取任何数组的数组切片,包括String.例如:

Name( 1 .. 3 )
Run Code Online (Sandbox Code Playgroud)

我们也可以在for循环中使用一个范围:

for I in 1 .. 10 loop
  --do something
end loop;
Run Code Online (Sandbox Code Playgroud)

或者,我们可以按如下方式迭代数组:

for I in X'Range loop
  X(I) := Function_Call;
end loop;
Run Code Online (Sandbox Code Playgroud)

所以,我目前的思路是"1 .. 3"形式的范围是Range文字,很像"3"是整数文字,而X'Range是一个返回索引范围的属性.数组X(或类似地,某些有序类型X,例如整数或枚举).

目前,我有一些看起来像这样的代码:

Name( 1 .. 3 )
Run Code Online (Sandbox Code Playgroud)

我一直认为这样的神奇数字不是一个好主意,所以我想我可以定义两个常量:

Name_Prefix_Range_Begin : constant Integer := 1;
Name_Prefix_Range_End   : constant Integer := 3;
Run Code Online (Sandbox Code Playgroud)

然后这样做:

Name( Name_Prefix_Range_Begin .. Name_Prefix_Range_End )
Run Code Online (Sandbox Code Playgroud)

但是,如果可以使用Range类型的常量,我觉得它会更清晰,只需编写以下代码来获取我的数组切片:

Name ( Name_Prefix_Range )
Run Code Online (Sandbox Code Playgroud)

那么,最后,在所有这些之后,是否可以声明一个可以存储范围的变量或常量?怎么写的?我已经做出了无法编译的猜测,并且未能找到任何关于这种可能性的参考.

ada

3
推荐指数
1
解决办法
899
查看次数

我们如何使用约束来确保数组的所有值都不是 NULL?

假设我有下表:

CREATE TABLE test (
    arr_column VARCHAR[] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

这不会阻止在插入行时将数组的值设置为 NULL。所以,我想要一个约束来强制执行这个规则。我的尝试如下:

CREATE TABLE test (
    arr_column VARCHAR[] NOT NULL 
        CHECK (NOT (ARRAY[NULL]::VARCHAR[] <@ arr_column))
)
Run Code Online (Sandbox Code Playgroud)

但不幸的是,如果我插入,这不会失败:

INSERT INTO test (ARRAY['some_string', NULL]::VARCHAR[])
Run Code Online (Sandbox Code Playgroud)

sql postgresql plpgsql

3
推荐指数
1
解决办法
157
查看次数

if和elsif优化在Ada 95中

我正在开发一个我不太熟悉的基于Ada的项目,我刚刚看到的东西乍一看似乎效率低下,但当然这一切都取决于编译器可能会做什么.

if Ada.Strings.Fixed.Trim
    (Source => Test_String,
     Side   => Ada.Strings.Both) =
    String_1 then
    --Do something here
elsif Ada.Strings.Fixed.Trim
    (Source => Test_String,
     Side   => Ada.Strings.Both) =
    String_2 then

    --Do something else here
end if;
Run Code Online (Sandbox Code Playgroud)

我觉得调用Trim过程并将结果存储在String变量中更有效,然后在if语句的每个条件中测试不同的字符串,特别是如果有许多条件需要检查(更别提使用二进制文件)搜索可能会更好).当然,我可能是错的,所以我的问题是,Ada中的编译时间优化是否有一些我不知道的事情,这可能导致Trim函数只被调用一次,并且只在每个条件下测试结果if语句?

ada

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

“无选择器”是什么意思?

我收到以下编译器错误:

time_types.ads:99 处未定义类型“Timestamp_Record_Type”的选择器“Put_Timestamp”

给出错误的代码行是:

Timestamp.Put_Timestamp(Trs_Time);
Run Code Online (Sandbox Code Playgroud)

该项目中的 Timestamp 和 Time_Types 包是在错误所在的同一文件的顶部导入的:

with Timestamp;
with Time_Types;
Run Code Online (Sandbox Code Playgroud)

timestamp.ads 包含以下内容:

with Ada.Calendar;

with Time_Types;


package Timestamp is


   function Calculate_Ada_Timestamp( Timestamp_Value : in Time_Types.Timestamp_Time_Type )
    return Ada.Calendar.Time;



  procedure Put_Timestamp
    (Timestamp: in Time_Types.Timestamp_Record_Type);

end Timestamp;
Run Code Online (Sandbox Code Playgroud)

起初我认为这个错误一定意味着带有 Timestamp_Record_Type 类型参数的 Put_Timestamp 不存在,但根据上面的代码,显然情况并非如此。

我缺少什么?

ada

2
推荐指数
1
解决办法
1895
查看次数

如何将 aws.WriteAtBuffer 转换为 io.Reader?

我需要从 S3 下载一个文件,然后将相同的文件上传到不同的 S3 存储桶中。到目前为止,我有:

sess := session.Must(session.NewSession())
downloader := s3manager.NewDownloader(sess)

buffer := aws.NewWriteAtBuffer([]byte{})

n, err := downloader.Download(buffer, &s3.GetObjectInput{
    Bucket: aws.String(sourceS3Bucket),
    Key:    aws.String(documentKey),
})

uploader := s3manager.NewUploader(sess)
result, err := uploader.Upload(&s3manager.UploadInput{
    Bucket: aws.String(targetS3Bucket),
    Key:    aws.String(documentKey),
    Body:   buffer,
})
Run Code Online (Sandbox Code Playgroud)

我使用了 aws.WriteAtBuffer,根据这里的答案:https ://stackoverflow.com/a/48254996/504055

但是,我目前坚持如何将此缓冲区视为实现 io.Reader 接口的东西,这是上传者的 Upload 方法所需要的。

amazon-s3 go

0
推荐指数
1
解决办法
899
查看次数