{"id":15494888,"url":"https://github.com/fracpete/sizeofag","last_synced_at":"2025-04-22T20:24:56.256Z","repository":{"id":28762925,"uuid":"32285147","full_name":"fracpete/sizeofag","owner":"fracpete","description":"Determining size of Java objects.","archived":false,"fork":false,"pushed_at":"2024-01-31T21:22:58.000Z","size":51,"stargazers_count":20,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-19T12:15:45.429Z","etag":null,"topics":["java","java-objects","memory"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"ScientistJake/NvER_plotter_django","license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fracpete.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-03-15T21:30:45.000Z","updated_at":"2024-07-29T14:11:54.000Z","dependencies_parsed_at":"2024-12-10T14:48:31.404Z","dependency_job_id":null,"html_url":"https://github.com/fracpete/sizeofag","commit_stats":{"total_commits":44,"total_committers":3,"mean_commits":"14.666666666666666","dds":0.2954545454545454,"last_synced_commit":"ac7873b46e25f946aefd9c86713b775eb9171050"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fracpete%2Fsizeofag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fracpete%2Fsizeofag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fracpete%2Fsizeofag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fracpete%2Fsizeofag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fracpete","download_url":"https://codeload.github.com/fracpete/sizeofag/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250317043,"owners_count":21410674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","java-objects","memory"],"created_at":"2024-10-02T08:15:31.530Z","updated_at":"2025-04-22T20:24:56.239Z","avatar_url":"https://github.com/fracpete.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sizeofag\n\n*sizeofag* is a Java Agent that allows you to determine the size of Java\nobjects from within the JVM at runtime. This makes it very useful for developing\nJava frameworks that take memory constraints into account. This project is based\non [Maxim Zakharenkov's code](http://jroller.com/maxim/entry/again_about_determining_size_of).\n\nPlease note, that the String class maintains an *internal pool* of String objects\nfor optimization reasons. These internal strings won't get counted \n(see [String.intern()](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--))\nand you may see 0 for some String objects.\n\n*sizeofag* is used, for instance, in [MOA (Massive Online Analysis)](http://moa.cms.waikato.ac.nz/),\na machine learning framework for data streams.\n\nMinimum Java version:\n* `\u003c= 1.0.4`: Java 6\n* `\u003e= 1.1.0`: Java 8\n\n\n## License\n*sizeofag* is released under [LGPL 3](http://www.gnu.org/licenses/lgpl-3.0.txt).\n\n## Maven\nInclude the following dependency in your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.fracpete\u003c/groupId\u003e\n  \u003cartifactId\u003esizeofag\u003c/artifactId\u003e\n  \u003cversion\u003e1.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n**NB:** You still need to add the `-javaagent` parameter to your Java call.\nSee example below for details.\n\n## Examples\n\nYou have to start up the JVM with the following additional parameter (adjusting\nthe path to the jar, of course):\n\n```bash\n-javaagent:/path/to/sizeofag-1.1.0.jar\n```\n\nIf your path contains spaces, then the whole parameter must be enclosed in double quotes:\n\n```bash\n\"-javaagent:/path/with some spaces/sizeofag-1.1.0.jar\"\n```\n\n### Total size\n\nThe following example code:\n\n```java\nimport sizeof.agent.SizeOfAgent;\n\npublic class SizeTest {\n\n  double d;\n  float f;\n  int i;\n  long l;\n\n  public static String[] randomStrings(int num) {\n    String[] result = new String[num];\n    for (int i = 0; i \u003c result.length; i++)\n      result[i] = \"\" + Math.random();\n    return result;\n  }\n\n  public static String randomString() {\n    return \"\" + Math.random();\n  }\n\n  public static void main(String[] args) {\n    // NB: The JVM maintains an internal pool of String objects.\n    // These \"internal\" String objects won't get counted, so you might\n    // see a count of 0 for some strings\n    System.out.println(\"String: \" + SizeOfAgent.fullSizeOf(\"Hello World\"));\n    System.out.println(\"int: \" + SizeOfAgent.fullSizeOf(2));\n    System.out.println(\"double: \" + SizeOfAgent.fullSizeOf(2.3));\n    System.out.println(\"float: \" + SizeOfAgent.fullSizeOf(1.5f));\n    System.out.println(\"Object: \" + SizeOfAgent.fullSizeOf(new SizeTest()));\n    System.out.println(\"int array: \" + SizeOfAgent.fullSizeOf(new int[]{1, 2, 3, 4}));\n    System.out.println(\"String array: \" + SizeOfAgent.fullSizeOf(new String[]{\"1\", \"2\", \"3\", \"4\"}));\n    System.out.println(\"Object array: \" + SizeOfAgent.fullSizeOf(new SizeTest[]{new SizeTest()}));\n    System.out.println(\"random String: \" + SizeOfAgent.fullSizeOf(randomString()));\n    System.out.println(\"random String array[1]: \" + SizeOfAgent.fullSizeOf(randomStrings(1)));\n    System.out.println(\"random String array[10]: \" + SizeOfAgent.fullSizeOf(randomStrings(10)));\n    System.out.println(\"random String array[1000]: \" + SizeOfAgent.fullSizeOf(randomStrings(1000)));\n    System.out.println(\"random String array[2000]: \" + SizeOfAgent.fullSizeOf(randomStrings(2000)));\n  }\n}\n```\n\nwill output something like this (21.0.1+12, 64bit on Linux):\n\n```\nString: 0\nint: 16\ndouble: 24\nfloat: 16\nObject: 40\nint array: 32\nString array: 32\nObject array: 64\nrandom String: 0\nrandom String array[1]: 24\nrandom String array[10]: 56\nrandom String array[1000]: 4016\nrandom String array[2000]: 8016\n```\n\n### Breakdown per class\n\nIt is also possible to break down the size per class by using the `fullSizePerClass` method as in the\nfollowing example. This method returns a map of `Class` to `sizeof.agent.Statistics` relation, with\nthe `Statistics` container class containing the accumulated size for the class and the number of\ninstances of this object were encountered. \n\n```java\nimport sizeof.agent.SizeOfAgent;\n\npublic class SizeTest {\n\n  double d;\n  float f;\n  int i;\n  long l;\n\n  public static class InnerClass {\n    double d;\n    float f;\n  }\n\n  public static class AnotherClass {\n    InnerClass inner = new InnerClass();\n  }\n\n  AnotherClass another1 = new AnotherClass();\n  AnotherClass another2 = new AnotherClass();\n  AnotherClass another3 = new AnotherClass();\n  InnerClass inner1 = new InnerClass();\n  InnerClass inner2 = new InnerClass();\n\n  public static void main(String[] args) {\n    System.out.println(\"AnotherClass (full): \" + SizeOfAgent.fullSizeOf(new AnotherClass()));\n    System.out.println(\"InnerClass (full): \" + SizeOfAgent.fullSizeOf(new InnerClass()));\n    System.out.println(\"SizeTest (full): \" + SizeOfAgent.fullSizeOf(new SizeTest()));\n    System.out.println(\"AnotherClass (per class): \" + SizeOfAgent.fullSizePerClass(new AnotherClass()));\n    System.out.println(\"InnerClass (per class): \" + SizeOfAgent.fullSizePerClass(new InnerClass()));\n    System.out.println(\"SizeTest (per class): \" + SizeOfAgent.fullSizePerClass(new SizeTest()));\n  }\n}\n```\n\nWill output something like this (21.0.1+12, 64bit on Linux):\n\n```\nAnotherClass (full): 40\nInnerClass (full): 24\nSizeTest (full): 224\nAnotherClass (per class): {class SizeTest$AnotherClass={count:1, total:16}, class SizeTest$InnerClass={count:1, total:24}}\nInnerClass (per class): {class SizeTest$InnerClass={count:1, total:24}}\nSizeTest (per class): {class SizeTest$AnotherClass={count:3, total:48}, class SizeTest={count:1, total:56}, class SizeTest$InnerClass={count:5, total:120}}\n```\n\n### Filtering\n\nWith the `sizeof.agent.Filter` class, you can influence how the calculation and\ntraversal is occurring:\n\n* `public boolean skipSuperClass(Class superclass);`\n\n  Allows you to stop the traversal up the class hierarchy.\n\n* `public boolean skipObject(Object obj);`\n\n  Here you can skip certain objects, e.g., ones that implement a certain \n  interface. The supplied object, however, is always inspected.\n\n* `public boolean skipField(Field field);`\n\n  With this method, you can avoid specific fields declared by the class of the \n  current object.\n\nThe following example class will skip instances of `InnerClass` in its \ncalculation:\n\n```java\nimport sizeof.agent.Filter;\nimport sizeof.agent.SizeOfAgent;\n\nimport java.lang.reflect.Field;\n\npublic class SizeTest {\n\n  double d;\n  float f;\n  int i;\n  long l;\n\n  public static class InnerClass {\n    double d;\n    float f;\n  }\n\n  public static class AnotherClass {\n    InnerClass inner = new InnerClass();\n  }\n\n  AnotherClass another1 = new AnotherClass();\n  AnotherClass another2 = new AnotherClass();\n  AnotherClass another3 = new AnotherClass();\n  InnerClass inner1 = new InnerClass();\n  InnerClass inner2 = new InnerClass();\n\n  public static void main(String[] args) {\n    Filter filter = new Filter() {\n      public boolean skipSuperClass(Class superclass) {\n        return false;\n      }\n      public boolean skipObject(Object obj) {\n        return (obj instanceof InnerClass);\n      }\n      public boolean skipField(Field field) {\n        return false;\n      }\n    };\n    System.out.println(\"AnotherClass (per class): \" + SizeOfAgent.fullSizePerClass(new AnotherClass(), filter));\n    System.out.println(\"InnerClass (per class): \" + SizeOfAgent.fullSizePerClass(new InnerClass(), filter));\n    System.out.println(\"SizeTest (per class): \" + SizeOfAgent.fullSizePerClass(new SizeTest(), filter));\n  }\n}\n```\n\nWill output something like this (21.0.1+12, 64bit on Linux):\n\n```\nAnotherClass (per class): {class SizeTest$AnotherClass={count:1, total:16}}\nInnerClass (per class): {class SizeTest$InnerClass={count:1, total:24}}\nSizeTest (per class): {class SizeTest$AnotherClass={count:3, total:48}, class SizeTest={count:1, total:56}}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffracpete%2Fsizeofag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffracpete%2Fsizeofag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffracpete%2Fsizeofag/lists"}