【问题标题】:Maxmind DatabaseReader Java heap spaceMaxmind DatabaseReader Java 堆空间
【发布时间】:2020-01-01 23:43:46
【问题描述】:

我尝试在 Spring Boot 中使用 GeoLite2-City.mmdb 来获取位置数据。为此,我在配置文件中创建了一个这样的 bean:

        @Bean   
        public static synchronized DatabaseReader mmdbReader() throws IOException { 

               if ( reader != null ) {
                   return reader;
               }

                ResourceLoader resourceLoader = new DefaultResourceLoader();

                Resource resource = resourceLoader.getResource("classpath:static/mmdb/GeoLite2-City.mmdb");
                InputStream database = resource.getInputStream();

               reader = new DatabaseReader.Builder(database).fileMode(com.maxmind.db.Reader.FileMode.MEMORY)
                       .withCache(new CHMCache()).build(); 

           return reader;
        }

我还创建了一个 util 函数来检索位置,如下所示:

     public static GeoLocation getLocation(HttpServletRequest request, DatabaseReader databaseReader) throws IOException, GeoIp2Exception{

      if(request.getRemoteAddr().equals("0:0:0:0:0:0:0:1") || request.getRemoteAddr().equals("127.0.0.1")) {
          return new GeoLocation("localhost", "Redmond", "USA", 47.673988, -122.121513);
      }

      InetAddress ipAddress = InetAddress.getByName(request.getRemoteAddr());

      CityResponse response = databaseReader.city(ipAddress);

      Country country = response.getCountry();
      City city = response.getCity();
      Location location = response.getLocation();

      return new GeoLocation(ipAddress.toString(), city.getName(), country.getName(), location.getLatitude(), location.getLongitude());
      }

但是,每次我部署应用程序时都会收到此错误


 Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3236)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at com.maxmind.db.BufferHolder.<init>(BufferHolder.java:64)
    at com.maxmind.db.Reader.<init>(Reader.java:89)
    at com.maxmind.geoip2.DatabaseReader.<init>(DatabaseReader.java:64)
    at com.maxmind.geoip2.DatabaseReader.<init>(DatabaseReader.java:54)

    at com.maxmind.geoip2.DatabaseReader$Builder.build(DatabaseReader.java:160)
    at com.microsoft.apie.configuration.ApplicationConfiguration.mmdbReader(ApplicationConfiguration.java:104)

我的 java 设置是:

  -Xms512m -Xmx2048m

你能帮忙吗?

【问题讨论】:

  • 该文件现在有多大?根据stackoverflow.com/questions/37483661/… 的说法,它相当小,但那是几年前的事了。
  • @mentallurg,DatabaseReader.java 和 Reader.java 以及 BufferHolder.java 是 maxmind 库的一部分,位于:github.com/maxmind/GeoIP2-java/blob/master/src/main/java/com/…
  • @tevemadar,文件大小为 63,517,885 字节;所以大约 65MB
  • 你应该使用默认的文件模式,即 MEMORY_MAPPED
  • @Strelok,它没有用。我收到此错误:原因:java.lang.IllegalArgumentException:使用 InputStream 时仅支持 FileMode.MEMORY

标签: java spring-boot maxmind geolite2 geolitecity


【解决方案1】:

我通过这样做解决了这个问题:

一个。我从 jar 中删除了文件 GeoLite2-City.mmdb 并放在与 jar 相同的文件夹中

b.我重构了方法和这个:

    @Bean  
    public static synchronized DatabaseReader mmdbReader() throws IOException { 

              if ( reader != null ) {
                  return reader;
              }

               /*ResourceLoader resourceLoader = new DefaultResourceLoader();

               Resource resource = resourceLoader.getResource("classpath:static/mmdb/GeoLite2-Country.mmdb");

               InputStream database = resource.getInputStream();
              */
               FileSystemResource resource = new FileSystemResource("/path/to/file/GeoLite2-City.mmdb");

              reader = new DatabaseReader.Builder(resource.getFile()).fileMode(com.maxmind.db.Reader.FileMode.MEMORY_MAPPED)
                      .withCache(new CHMCache()).build(); 

          return reader;
   }

c。重新打包应用程序,它的工作原理!

感谢 Strelok 的建议

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多